public int PopulateChunk(ChunkColumn chunk)
        {
            //var random = new CryptoRandom();
            //var stones = new byte[16*16*16];
            int h = 0;

            for (int x = 0; x < 16; x++)
            {
                for (int z = 0; z < 16; z++)
                {
                    h = 0;

                    chunk.SetBlock(x, h++, z, 7);                     // Bedrock

                    //stones[i + h++] = 1; // Stone
                    //stones[i + h++] = 1; // Stone

                    //switch (random.Next(0, 20))
                    //{
                    //	case 0:
                    //		stones[i + h++] = 3; // Dirt
                    //		stones[i + h++] = 3;
                    //		break;
                    //	case 1:
                    //		stones[i + h++] = 1; // Stone
                    //		stones[i + h++] = 1; // Stone
                    //		break;
                    //	case 2:
                    //		stones[i + h++] = 13; // Gravel
                    //		stones[i + h++] = 13; // Gravel
                    //		break;
                    //	case 3:
                    //		stones[i + h++] = 14; // Gold
                    //		stones[i + h++] = 14; // Gold
                    //		break;
                    //	case 4:
                    //		stones[i + h++] = 16; // Cole
                    //		stones[i + h++] = 16; // Cole
                    //		break;
                    //	case 5:
                    //		stones[i + h++] = 56; // Dimond
                    //		stones[i + h++] = 56; // Dimond
                    //		break;
                    //	default:
                    //		stones[i + h++] = 1; // Stone
                    //		stones[i + h++] = 1; // Stone
                    //		break;
                    //}
                    chunk.SetBlock(x, h++, z, 3);                     // Dirt
                    chunk.SetBlock(x, h++, z, 3);                     // Dirt
                    chunk.SetBlock(x, h++, z, 2);                     // Grass
                    chunk.SetHeight(x, z, (short)h);
                }
            }

            return(h);
        }
Exemple #2
0
        private void BuildStructures(ChunkColumn chunk)
        {
            if (chunk.x == 0 && chunk.z == 1)
            {
                for (int x = 3; x < 6; x++)
                {
                    for (int y = 4; y < 7; y++)
                    {
                        if (x == 4 && y < 6)
                        {
                            continue;
                        }

                        for (int z = 1; z < 15; z++)
                        {
                            chunk.SetBlock(x, y, z, 3);
                        }
                    }
                }
                chunk.SetBlock(4, 4, 14, 3);
                chunk.SetBlock(4, 5, 14, 3);
            }

            //if (chunk.x == 0 && chunk.z == 0)
            //{
            //	for (int x = 1; x < 16; x++)
            //	{
            //		for (int z = 0; z < 16; z++)
            //		{
            //			chunk.SetBlock(x, 8, z, 3);
            //		}
            //	}
            //}
            //if (chunk.x == 1 && chunk.z == 0)
            //{
            //	for (int x = 0; x < 15; x++)
            //	{
            //		for (int z = 0; z < 16; z++)
            //		{
            //			chunk.SetBlock(x, 8, z, 3);
            //		}
            //	}
            //}

            if (chunk.x == -1 && chunk.z == 0)
            {
                for (int x = 1; x < 15; x++)
                {
                    for (int z = 1; z < 15; z++)
                    {
                        chunk.SetBlock(x, 8, z, 3);
                    }
                }
            }
        }
Exemple #3
0
        private void GenerateLake(Random random, ChunkColumn chunk, Block block)
        {
            int h = FindGroundLevel();

            if (h < 0)
            {
                return;
            }

            Vector2 center = new Vector2(7, 8);

            for (int x = 0; x < 16; x++)
            {
                for (int z = 0; z < 16; z++)
                {
                    Vector2 v = new Vector2(x, z);
                    if (random.Next((int)Vector2.DistanceSquared(center, v)) < 4)
                    {
                        if (Dimension == Dimension.Overworld)
                        {
                            chunk.SetBlock(x, h, z, block.Id);
                        }
                        else if (Dimension == Dimension.Nether)
                        {
                            chunk.SetBlock(x, h, z, block.Id);

                            if (random.Next(30) == 0)
                            {
                                for (int i = h; i < BlockLayers.Count - 1; i++)
                                {
                                    chunk.SetBlock(x, i, z, block.Id);
                                }
                            }
                        }
                        else if (Dimension == Dimension.TheEnd)
                        {
                            for (int i = 0; i < BlockLayers.Count; i++)
                            {
                                chunk.SetBlock(x, i, z, 0);
                            }
                        }
                    }
                    else if (Dimension == Dimension.TheEnd && random.Next((int)Vector2.DistanceSquared(center, v)) < 15)
                    {
                        chunk.SetBlock(x, h, z, 0);
                    }
                }
            }
        }
Exemple #4
0
        public void PopulateChunk(ChunkColumn chunk)
        {
            var layers = BlockLayers;

            for (int x = 0; x < 16; x++)
            {
                for (int z = 0; z < 16; z++)
                {
                    int h = 0;

                    foreach (var layer in layers)
                    {
                        chunk.SetBlock(x, h, z, layer.Id);
                        chunk.SetMetadata(x, h, z, layer.Metadata);
                        h++;
                    }

                    chunk.SetHeight(x, z, (short)h);
                    for (int i = h + Dimension == Dimension.Overworld ? 1 : 0; i >= 0; i--)
                    {
                        chunk.SetSkyLight(x, i, z, 0);
                    }

                    // need to take care of skylight for non overworld to make it 0.

                    chunk.SetBiome(x, z, 1);                     // use pattern for this
                }
            }
        }
Exemple #5
0
        public void SetBlock(Block block, bool broadcast = true, bool applyPhysics = true)
        {
            ChunkColumn chunk = _worldProvider.GenerateChunkColumn(new ChunkCoordinates(block.Coordinates.X >> 4, block.Coordinates.Z >> 4));

            chunk.SetBlock(block.Coordinates.X & 0x0f, block.Coordinates.Y & 0x7f, block.Coordinates.Z & 0x0f, block.Id);
            chunk.SetMetadata(block.Coordinates.X & 0x0f, block.Coordinates.Y & 0x7f, block.Coordinates.Z & 0x0f, block.Metadata);

            if (applyPhysics)
            {
                ApplyPhysics(block.Coordinates.X, block.Coordinates.Y, block.Coordinates.Z);
            }

            if (!broadcast)
            {
                return;
            }

            Block sendBlock = new Block(block.Id)
            {
                Coordinates = block.Coordinates,
                Metadata    = (byte)(0xb << 4 | (block.Metadata & 0xf))
            };

            var message = McpeUpdateBlock.CreateObject();

            message.blocks = new BlockRecords {
                sendBlock
            };
            RelayBroadcast(message);
        }
Exemple #6
0
        public void SetBlock(Block block, bool broadcast = true, bool applyPhysics = true, bool calculateLight = true)
        {
            if (block.Coordinates.Y < 0)
            {
                return;
            }

            ChunkColumn chunk = _worldProvider.GenerateChunkColumn(new ChunkCoordinates(block.Coordinates.X >> 4, block.Coordinates.Z >> 4));

            chunk.SetBlock(block.Coordinates.X & 0x0f, block.Coordinates.Y & 0xff, block.Coordinates.Z & 0x0f, block.Id);
            chunk.SetMetadata(block.Coordinates.X & 0x0f, block.Coordinates.Y & 0xff, block.Coordinates.Z & 0x0f, block.Metadata);

            if (applyPhysics)
            {
                ApplyPhysics(block.Coordinates.X, block.Coordinates.Y, block.Coordinates.Z);
            }
            if (block.LightLevel > 0)
            {
                block.BlockLight = (byte)block.LightLevel;
                chunk.SetBlocklight(block.Coordinates.X & 0x0f, block.Coordinates.Y & 0xff, block.Coordinates.Z & 0x0f, (byte)block.LightLevel);
                BlockLightCalculations.Calculate(this, block);
            }

            if (!broadcast)
            {
                return;
            }

            var message = McpeUpdateBlock.CreateObject();

            message.blockId              = block.Id;
            message.coordinates          = block.Coordinates;
            message.blockMetaAndPriority = (byte)(0xb << 4 | (block.Metadata & 0xf));
            RelayBroadcast(message);
        }
Exemple #7
0
        public void SetBlock(Block block, bool broadcast = true, bool applyPhysics = true)
        {
            ChunkColumn chunk = _worldProvider.GenerateChunkColumn(new ChunkCoordinates(block.Coordinates.X >> 4, block.Coordinates.Z >> 4));

            chunk.SetBlock(block.Coordinates.X & 0x0f, block.Coordinates.Y & 0x7f, block.Coordinates.Z & 0x0f, block.Id);
            chunk.SetMetadata(block.Coordinates.X & 0x0f, block.Coordinates.Y & 0x7f, block.Coordinates.Z & 0x0f, block.Metadata);

            if (applyPhysics)
            {
                ApplyPhysics(block.Coordinates.X, block.Coordinates.Y, block.Coordinates.Z);
            }

            if (!broadcast)
            {
                return;
            }

            var message = McpeUpdateBlock.CreateObject();

            message.blockId = block.Id;
            message.x       = block.Coordinates.X;
            message.y       = (byte)block.Coordinates.Y;
            message.z       = block.Coordinates.Z;
            message.blockMetaAndPriority = (byte)(0xb << 4 | (block.Metadata & 0xf));
            RelayBroadcast(message);
        }
Exemple #8
0
        private void GenerateGlowStone(Random random, ChunkColumn chunk)
        {
            if (Dimension != Dimension.Nether)
            {
                return;
            }

            int h = FindGroundLevel();

            if (h < 0)
            {
                return;
            }

            Vector2 center = new Vector2(7, 8);

            for (int x = 0; x < 16; x++)
            {
                for (int z = 0; z < 16; z++)
                {
                    Vector2 v = new Vector2(x, z);
                    if (random.Next((int)Vector2.DistanceSquared(center, v)) < 1)
                    {
                        chunk.SetBlock(x, BlockLayers.Count - 2, z, new Glowstone().Id);
                        if (random.NextDouble() > 0.85)
                        {
                            chunk.SetBlock(x, BlockLayers.Count - 3, z, new Glowstone().Id);
                            if (random.NextDouble() > 0.50)
                            {
                                chunk.SetBlock(x, BlockLayers.Count - 4, z, new Glowstone().Id);
                            }
                        }
                    }
                }
            }
        }
Exemple #9
0
        public void ShowHeights(ChunkColumn chunk)
        {
            if (chunk == null)
            {
                return;
            }

            for (int x = 0; x < 16; x++)
            {
                for (int z = 0; z < 16; z++)
                {
                    for (byte y = 255; y > 0; y--)
                    {
                        if (chunk.GetSkylight(x, y, z) == 0)
                        {
                            chunk.SetBlock(x, y, z, 41);
                        }
                    }
                }
            }
        }
        public void ShowHeights(ChunkColumn chunk)
        {
            if (chunk == null)
            {
                return;
            }

            for (int x = 0; x < 16; x++)
            {
                for (int z = 0; z < 16; z++)
                {
                    var y = chunk.GetHeight(x, z);
                    chunk.SetBlock(x, y, z, 41);
                    //for (byte y = 255; y > 0; y--)
                    //{
                    //	if (chunk.GetSkylight(x, y, z) == 0)
                    //	{
                    //		chunk.SetBlock(x, y, z, 41);
                    //		break;
                    //	}
                    //}
                }
            }
        }
        public ChunkColumn GenerateChunkColumn(ChunkCoordinates chunkCoordinates)
        {
            lock (_chunkCache)
            {
                ChunkColumn cachedChunk;
                if (_chunkCache.TryGetValue(chunkCoordinates, out cachedChunk))
                {
                    return(cachedChunk);
                }

                ChunkColumn chunk = new ChunkColumn();
                chunk.x = chunkCoordinates.X;
                chunk.z = chunkCoordinates.Z;
                //chunk.biomeId = ArrayOf<byte>.Create(256, (byte) rand.Next(0, 37));

                int h = PopulateChunk(chunk);

                //chunk.SetBlock(0, h + 1, 0, 7);
                //chunk.SetBlock(1, h + 1, 0, 41);
                //chunk.SetBlock(2, h + 1, 0, 41);
                //chunk.SetBlock(3, h + 1, 0, 41);
                //chunk.SetBlock(3, h + 1, 0, 41);

                ////chunk.SetBlock(6, h + 1, 6, 57);

                //chunk.SetBlock(9, h, 3, 31);
                //chunk.SetBiome(9, 3, 30);
                //chunk.SetBlock(0, h, 1, 161);
                //chunk.SetBlock(0, h, 2, 18);

                //chunk.SetBlock(0, h, 15, 31);
                //chunk.SetBlock(0, h, 14, 161);
                //chunk.SetBlock(5, h, 13, 18);
                //chunk.SetBiome(5, 13, 30);

                //chunk.SetBlock(6, h, 9, 63);
                //chunk.SetMetadata(6, h, 9, 12);
                //var blockEntity = GetBlockEntity((chunkCoordinates.X*16) + 6, h, (chunkCoordinates.Z*16) + 9);
                //chunk.SetBlockEntity(blockEntity.Coordinates, blockEntity.GetCompound());

                if (chunkCoordinates.X == 1 && chunkCoordinates.Z == 1)
                {
                    for (int x = 0; x < 10; x++)
                    {
                        for (int z = 0; z < 10; z++)
                        {
                            for (int y = h - 2; y < h; y++)
                            {
                                chunk.SetBlock(x, y, z, 8);
                            }
                        }
                    }
                }

                if (chunkCoordinates.X == 3 && chunkCoordinates.Z == 1)
                {
                    for (int x = 0; x < 10; x++)
                    {
                        for (int z = 0; z < 10; z++)
                        {
                            for (int y = h - 1; y < h; y++)
                            {
                                chunk.SetBlock(x, y, z, 10);
                            }
                        }
                    }
                }

                for (int x = 0; x < 16; x++)
                {
                    for (int z = 0; z < 16; z++)
                    {
                        for (int y = 127; y > 0; y--)
                        {
                            if (chunk.GetBlock(x, y, z) == 0x00)
                            {
                                chunk.SetSkylight(x, y, z, 0xff);
                            }
                            else
                            {
                                chunk.SetSkylight(x, y, z, 0x00);
                            }
                        }
                    }
                }

                // Cache
                chunk.GetBatch();
                _chunkCache[chunkCoordinates] = chunk;

                return(chunk);
            }
        }
Exemple #12
0
        private void PopulateChunk(ChunkColumn chunk)
        {
            int trees = new Random().Next(0, 10);

            int[,] treeBasePositions = new int[trees, 2];

            for (int t = 0; t < trees; t++)
            {
                int x = new Random().Next(1, 16);
                int z = new Random().Next(1, 16);
                treeBasePositions[t, 0] = x;
                treeBasePositions[t, 1] = z;
            }

            var bottom   = new SimplexOctaveGenerator(_seed.GetHashCode(), 8);
            var overhang = new SimplexOctaveGenerator(_seed.GetHashCode(), 8);

            overhang.SetScale(1 / 64.0);
            bottom.SetScale(1 / 128.0);

            double overhangsMagnitude = 16;
            double bottomsMagnitude   = 32;

            for (int x = 0; x < 16; x++)
            {
                for (int z = 0; z < 16; z++)
                {
                    float ox = x + chunk.x * 16;
                    float oz = z + chunk.z * 16;


                    int bottomHeight = (int)((bottom.Noise(ox, oz, 0.5, 0.5) * bottomsMagnitude) + 64.0);
                    int maxHeight    = (int)((overhang.Noise(ox, oz, 0.5, 0.5) * overhangsMagnitude) + bottomHeight + 32.0);

                    double threshold = 0.0;

                    maxHeight = Math.Max(1, maxHeight);

                    for (int y = 0; y < maxHeight && y < 255; y++)
                    {
                        if (y <= 1)
                        {
                            chunk.SetBlock(x, y, z, 7);
                            continue;
                        }

                        if (y > bottomHeight)
                        {
                            //part where we do the overhangs
                            double density = overhang.Noise(ox, y, oz, 0.5, 0.5);
                            if (density > threshold)
                            {
                                chunk.SetBlock(x, y, z, (byte)Material.Stone);
                            }
                        }
                        else
                        {
                            chunk.SetBlock(x, y, z, (byte)Material.Stone);
                        }
                    }

                    //turn the tops into grass
                    chunk.SetBlock(x, bottomHeight, z, (byte)Material.Grass);                      //the top of the base hills
                    chunk.SetBlock(x, bottomHeight - 1, z, (byte)Material.Dirt);
                    chunk.SetBlock(x, bottomHeight - 2, z, (byte)Material.Dirt);

                    for (int y = bottomHeight + 1; y > bottomHeight && y < maxHeight && y < 255; y++)
                    {
                        //the overhang
                        int thisblock  = chunk.GetBlock(x, y, z);
                        int blockabove = chunk.GetBlock(x, y + 1, z);

                        if (thisblock != (decimal)Material.Air && blockabove == (decimal)Material.Air)
                        {
                            if (chunk.GetBlock(x, y, z) == (byte)Material.Dirt || chunk.GetBlock(x, y, z) == (byte)Material.Air || chunk.GetBlock(x, y, z) == (byte)Material.Stone)
                            {
                                chunk.SetBlock(x, y, z, (byte)Material.Grass);
                            }
                            if (chunk.GetBlock(x, y - 1, z) != (decimal)Material.Air)
                            {
                                chunk.SetBlock(x, y - 1, z, (byte)Material.Dirt);
                            }
                            if (chunk.GetBlock(x, y - 2, z) != (decimal)Material.Air)
                            {
                                chunk.SetBlock(x, y - 2, z, (byte)Material.Dirt);
                            }
                        }
                    }

                    for (int y = 0; y < WaterLevel; y++)
                    {
                        //Lake generation
                        if (y < WaterLevel)
                        {
                            if (chunk.GetBlock(x, y, z) == (decimal)Material.Grass || chunk.GetBlock(x, y, z) == (decimal)Material.Dirt)                               //Grass or Dirt?
                            {
                                if (GetRandomNumber(1, 40) == 1 && y < WaterLevel - 4)
                                {
                                    chunk.SetBlock(x, y, z, 82);                                     //Clay
                                }
                                else
                                {
                                    chunk.SetBlock(x, y, z, 12);                                     //Sand
                                }
                            }
                            if (chunk.GetBlock(x, y + 1, z) == (decimal)Material.Air)
                            {
                                if (y < WaterLevel - 3)
                                {
                                    chunk.SetBlock(x, y + 1, z, 8);                                     //FlowingWater
                                }
                            }
                        }
                    }

                    for (int y = 0; y < 255; y++)
                    {
                        int thisblock  = chunk.GetBlock(x, y, z);
                        int blockabove = chunk.GetBlock(x, y + 1, z);
                        if (thisblock == (decimal)Material.Grass && blockabove == (decimal)Material.Air && y > WaterLevel)
                        {
                            //Grass
                            if (GetRandomNumber(0, 5) == 1)
                            {
                                chunk.SetBlock(x, y + 1, z, 31);
                                chunk.SetMetadata(x, y + 1, z, 1);
                            }

                            //Flowers
                            if (GetRandomNumber(0, 65) == 1)
                            {
                                int meta = GetRandomNumber(0, 8);
                                chunk.SetBlock(x, y + 1, z, 38);
                                chunk.SetMetadata(x, y + 1, z, (byte)meta);
                            }

                            //Trees
                            for (int pos = 0; pos < trees; pos++)
                            {
                                if (treeBasePositions[pos, 0] < 14 && treeBasePositions[pos, 0] > 4 && treeBasePositions[pos, 1] < 14 &&
                                    treeBasePositions[pos, 1] > 4)
                                {
                                    if (chunk.GetBlock(treeBasePositions[pos, 0], y + 1, treeBasePositions[pos, 1]) == 2)
                                    {
                                        if (y >= bottomHeight)
                                        {
                                            GenerateTree(chunk, treeBasePositions[pos, 0], y + 1, treeBasePositions[pos, 1], WoodType.Oak);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        private void GenerateTree(ChunkColumn chunk, int x, int treebase, int z)
        {
            int treeheight = GetRandomNumber(4, 5);

            chunk.SetBlock(x, treebase + treeheight + 2, z, 18);             //Top leave

            chunk.SetBlock(x, treebase + treeheight + 1, z + 1, 18);
            chunk.SetBlock(x, treebase + treeheight + 1, z - 1, 18);
            chunk.SetBlock(x + 1, treebase + treeheight + 1, z, 18);
            chunk.SetBlock(x - 1, treebase + treeheight + 1, z, 18);

            chunk.SetBlock(x, treebase + treeheight, z + 1, 18);
            chunk.SetBlock(x, treebase + treeheight, z - 1, 18);
            chunk.SetBlock(x + 1, treebase + treeheight, z, 18);
            chunk.SetBlock(x - 1, treebase + treeheight, z, 18);

            chunk.SetBlock(x + 1, treebase + treeheight, z + 1, 18);
            chunk.SetBlock(x - 1, treebase + treeheight, z - 1, 18);
            chunk.SetBlock(x + 1, treebase + treeheight, z - 1, 18);
            chunk.SetBlock(x - 1, treebase + treeheight, z + 1, 18);

            for (int i = 0; i <= treeheight; i++)
            {
                chunk.SetBlock(x, treebase + i, z, 17);
            }
        }
Exemple #14
0
        private void ReadSection(int yoffset, NbtTag sectionTag, ChunkColumn chunk)
        {
            int sy = sectionTag["Y"].ByteValue * 16;

            byte[] blocks = sectionTag["Blocks"].ByteArrayValue;
            byte[] data   = sectionTag["Data"].ByteArrayValue;
            NbtTag addTag = sectionTag["Add"];

            byte[] adddata = new byte[2048];
            if (addTag != null)
            {
                adddata = addTag.ByteArrayValue;
            }
            byte[] blockLight = sectionTag["BlockLight"].ByteArrayValue;
            byte[] skyLight   = sectionTag["SkyLight"].ByteArrayValue;

            for (int x = 0; x < 16; x++)
            {
                for (int z = 0; z < 16; z++)
                {
                    for (int y = 0; y < 16; y++)
                    {
                        int yi = sy + y - yoffset;
                        if (yi < 0 || yi >= 256)
                        {
                            continue;
                        }

                        int anvilIndex = y * 16 * 16 + z * 16 + x;
                        int blockId    = blocks[anvilIndex] + (Nibble4(adddata, anvilIndex) << 8);

                        // Anvil to PE friendly converstion

                        Func <int, byte, byte> dataConverter = (i, b) => b;                        // Default no-op converter
                        if (Convert.ContainsKey(blockId))
                        {
                            dataConverter = Convert[blockId].Item2;
                            blockId       = Convert[blockId].Item1;
                        }
                        else
                        {
                            if (BlockFactory.GetBlockById((byte)blockId).GetType() == typeof(Block))
                            {
                                Log.Warn($"No block implemented for block ID={blockId}, Meta={data}");
                                //blockId = 57;
                            }
                        }

                        chunk.isAllAir = chunk.isAllAir && blockId == 0;
                        if (blockId > 255)
                        {
                            Log.Warn($"Failed mapping for block ID={blockId}, Meta={data}");
                            blockId = 41;
                        }

                        //if (yi == 127 && blockId != 0) blockId = 30;
                        if (yi == 0 && (blockId == 8 || blockId == 9))
                        {
                            blockId = 7;
                        }

                        chunk.SetBlock(x, yi, z, (byte)blockId);
                        byte metadata = Nibble4(data, anvilIndex);
                        metadata = dataConverter(blockId, metadata);

                        chunk.SetMetadata(x, yi, z, metadata);
                        chunk.SetBlocklight(x, yi, z, Nibble4(blockLight, anvilIndex));
                        chunk.SetSkyLight(x, yi, z, Nibble4(skyLight, anvilIndex));

                        //if (block is BlockStairs || block is StoneSlab || block is WoodSlab)
                        //{
                        //	chunk.SetSkylight(x, yi, z, 0xff);
                        //}

                        if (blockId == 43 && chunk.GetMetadata(x, yi, z) == 7)
                        {
                            chunk.SetMetadata(x, yi, z, 6);
                        }
                        else if (blockId == 44 && chunk.GetMetadata(x, yi, z) == 7)
                        {
                            chunk.SetMetadata(x, yi, z, 6);
                        }
                        else if (blockId == 44 && chunk.GetMetadata(x, yi, z) == 15)
                        {
                            chunk.SetMetadata(x, yi, z, 14);
                        }
                        else if (blockId == 3 && chunk.GetMetadata(x, yi, z) == 1)
                        {
                            // Dirt Course => (Grass Path)
                            chunk.SetBlock(x, yi, z, 198);
                            chunk.SetMetadata(x, yi, z, 0);
                        }
                        else if (blockId == 3 && chunk.GetMetadata(x, yi, z) == 2)
                        {
                            // Dirt Podzol => (Podzol)
                            chunk.SetBlock(x, yi, z, 243);
                            chunk.SetMetadata(x, yi, z, 0);
                        }
                        var block = BlockFactory.GetBlockById(chunk.GetBlock(x, yi, z));
                        if (block.LightLevel > 0)
                        {
                            block.Coordinates = new BlockCoordinates(x + (16 * chunk.x), yi, z + (16 * chunk.z));
                            LightSources.Enqueue(block);
                        }
                    }
                }
            }
        }
        private void PopulateChunk(ChunkColumn chunk)
        {
            int trees = new Random().Next(0, 10);

            int[,] treeBasePositions = new int[trees, 2];

            for (int t = 0; t < trees; t++)
            {
                int x = new Random().Next(1, 16);
                int z = new Random().Next(1, 16);
                treeBasePositions[t, 0] = x;
                treeBasePositions[t, 1] = z;
            }

            for (int x = 0; x < 16; x++)
            {
                for (int z = 0; z < 16; z++)
                {
                    int stoneHeight = (int)Math.Floor(stoneBaseHeight);
                    stoneHeight += GetNoise(chunk.x * 16 + x, chunk.z * 16 + z, stoneMountainFrequency, (int)Math.Floor(stoneMountainHeight));

                    if (stoneHeight < stoneMinHeight)
                    {
                        stoneHeight = (int)Math.Floor(stoneMinHeight);
                    }

                    stoneHeight += GetNoise(chunk.x * 16 + x, chunk.z * 16 + z, stoneBaseNoise, (int)Math.Floor(stoneBaseNoiseHeight));

                    int dirtHeight = stoneHeight + (int)Math.Floor(dirtBaseHeight);
                    dirtHeight += GetNoise(chunk.x * 16 + x, chunk.z * 16 + z, dirtNoise, (int)Math.Floor(dirtNoiseHeight));

                    for (int y = 0; y < 256; y++)
                    {
                        //float y2 = Get3DNoise(chunk.X*16, y, chunk.Z*16, stoneBaseNoise, (int) Math.Floor(stoneBaseNoiseHeight));
                        if (y <= stoneHeight)
                        {
                            chunk.SetBlock(x, y, z, 1);

                            //Diamond ore
                            if (GetRandomNumber(0, 2500) < 5)
                            {
                                chunk.SetBlock(x, y, z, 56);
                            }

                            //Coal Ore
                            if (GetRandomNumber(0, 1500) < 50)
                            {
                                chunk.SetBlock(x, y, z, 16);
                            }

                            //Iron Ore
                            if (GetRandomNumber(0, 2500) < 30)
                            {
                                chunk.SetBlock(x, y, z, 15);
                            }

                            //Gold Ore
                            if (GetRandomNumber(0, 2500) < 20)
                            {
                                chunk.SetBlock(x, y, z, 14);
                            }
                        }

                        if (y < waterLevel)                                                   //FlowingWater :)
                        {
                            if (chunk.GetBlock(x, y, z) == 2 || chunk.GetBlock(x, y, z) == 3) //Grass or Dirt?
                            {
                                if (GetRandomNumber(1, 40) == 5 && y < waterLevel - 4)
                                {
                                    chunk.SetBlock(x, y, z, 82);                                     //Clay
                                }
                                else
                                {
                                    chunk.SetBlock(x, y, z, 12);                                     //Sand
                                }
                            }
                            if (y < waterLevel - 3)
                            {
                                chunk.SetBlock(x, y + 1, z, 8);                                 //FlowingWater
                            }
                        }

                        if (y <= dirtHeight && y >= stoneHeight)
                        {
                            chunk.SetBlock(x, y, z, 3);                             //Dirt
                            chunk.SetBlock(x, y + 1, z, 2);                         //Grass Block
                            if (y > waterLevel)
                            {
                                //Grass
                                if (GetRandomNumber(0, 5) == 2)
                                {
                                    chunk.SetBlock(x, y + 2, z, 31);
                                    chunk.SetMetadata(x, y + 2, z, 1);
                                }

                                //flower
                                if (GetRandomNumber(0, 65) == 8)
                                {
                                    int meta = GetRandomNumber(0, 8);
                                    chunk.SetBlock(x, y + 2, z, 38);
                                    chunk.SetMetadata(x, y + 2, z, (byte)meta);
                                }

                                for (int pos = 0; pos < trees; pos++)
                                {
                                    if (treeBasePositions[pos, 0] < 14 && treeBasePositions[pos, 0] > 4 && treeBasePositions[pos, 1] < 14 &&
                                        treeBasePositions[pos, 1] > 4)
                                    {
                                        if (y < waterLevel + 2)
                                        {
                                            break;
                                        }
                                        if (chunk.GetBlock(treeBasePositions[pos, 0], y + 1, treeBasePositions[pos, 1]) == 2)
                                        {
                                            if (y == dirtHeight)
                                            {
                                                GenerateTree(chunk, treeBasePositions[pos, 0], y + 1, treeBasePositions[pos, 1]);
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        if (y == 0)
                        {
                            chunk.SetBlock(x, y, z, 7);
                        }
                    }
                }
            }
        }
Exemple #16
0
        public static ChunkColumn GetChunk(ChunkCoordinates coordinates, string basePath, IWorldProvider generator, int yoffset)
        {
            int width = 32;
            int depth = 32;

            int rx = coordinates.X >> 5;
            int rz = coordinates.Z >> 5;

            string filePath = Path.Combine(basePath, string.Format(@"region\r.{0}.{1}.mca", rx, rz));

            if (!File.Exists(filePath))
            {
                return(generator.GenerateChunkColumn(coordinates));
            }

            using (var regionFile = File.OpenRead(filePath))
            {
                byte[] buffer = new byte[8192];

                regionFile.Read(buffer, 0, 8192);

                int xi = (coordinates.X % width);
                if (xi < 0)
                {
                    xi += 32;
                }
                int zi = (coordinates.Z % depth);
                if (zi < 0)
                {
                    zi += 32;
                }
                int tableOffset = (xi + zi * width) * 4;

                regionFile.Seek(tableOffset, SeekOrigin.Begin);

                byte[] offsetBuffer = new byte[4];
                regionFile.Read(offsetBuffer, 0, 3);
                Array.Reverse(offsetBuffer);
                int offset = BitConverter.ToInt32(offsetBuffer, 0) << 4;

                int length = regionFile.ReadByte();

                if (offset == 0 || length == 0)
                {
                    return(generator.GenerateChunkColumn(coordinates));
                }

                regionFile.Seek(offset, SeekOrigin.Begin);
                byte[] waste = new byte[4];
                regionFile.Read(waste, 0, 4);
                int compressionMode = regionFile.ReadByte();

                var nbt = new NbtFile();
                nbt.LoadFromStream(regionFile, NbtCompression.ZLib);

                NbtTag dataTag = nbt.RootTag["Level"];

                NbtList sections = dataTag["Sections"] as NbtList;

                ChunkColumn chunk = new ChunkColumn
                {
                    x       = coordinates.X,
                    z       = coordinates.Z,
                    biomeId = dataTag["Biomes"].ByteArrayValue
                };

                for (int i = 0; i < chunk.biomeId.Length; i++)
                {
                    if (chunk.biomeId[i] > 22)
                    {
                        chunk.biomeId[i] = 0;
                    }
                }
                if (chunk.biomeId.Length > 256)
                {
                    throw new Exception();
                }

                // This will turn into a full chunk column
                foreach (NbtTag sectionTag in sections)
                {
                    int    sy      = sectionTag["Y"].ByteValue * 16;
                    byte[] blocks  = sectionTag["Blocks"].ByteArrayValue;
                    byte[] data    = sectionTag["Data"].ByteArrayValue;
                    NbtTag addTag  = sectionTag["Add"];
                    byte[] adddata = new byte[2048];
                    if (addTag != null)
                    {
                        adddata = addTag.ByteArrayValue;
                    }
                    byte[] blockLight = sectionTag["BlockLight"].ByteArrayValue;
                    byte[] skyLight   = sectionTag["SkyLight"].ByteArrayValue;

                    for (int x = 0; x < 16; x++)
                    {
                        for (int z = 0; z < 16; z++)
                        {
                            for (int y = 0; y < 16; y++)
                            {
                                int yi = sy + y - yoffset;
                                if (yi < 0 || yi >= 128)
                                {
                                    continue;
                                }

                                int anvilIndex = y * 16 * 16 + z * 16 + x;
                                int blockId    = blocks[anvilIndex] + (Nibble4(adddata, anvilIndex) << 8);

                                // Anvil to PE friendly converstion
                                if (blockId == 125)
                                {
                                    blockId = 5;
                                }
                                else if (blockId == 126)
                                {
                                    blockId = 158;
                                }
                                else if (blockId == 75)
                                {
                                    blockId = 50;
                                }
                                else if (blockId == 76)
                                {
                                    blockId = 50;
                                }
                                else if (blockId == 123)
                                {
                                    blockId = 89;
                                }
                                else if (blockId == 124)
                                {
                                    blockId = 89;
                                }
                                else if (blockId == 152)
                                {
                                    blockId = 73;
                                }
                                else if (_ignore.BinarySearch(blockId) >= 0)
                                {
                                    blockId = 0;
                                }
                                else if (_gaps.BinarySearch(blockId) >= 0)
                                {
                                    Debug.WriteLine("Missing material: " + blockId);
                                    blockId = 133;
                                }

                                if (blockId > 255)
                                {
                                    blockId = 41;
                                }

                                if (yi == 127 && blockId != 0)
                                {
                                    blockId = 30;
                                }
                                if (yi == 0 && (blockId == 8 || blockId == 9 /*|| blockId == 0*/))
                                {
                                    blockId = 7;
                                }

                                //if (blockId != 0) blockId = 41;

                                chunk.SetBlock(x, yi, z, (byte)blockId);
                                chunk.SetMetadata(x, yi, z, Nibble4(data, anvilIndex));
                                chunk.SetBlocklight(x, yi, z, Nibble4(blockLight, anvilIndex));
                                chunk.SetSkylight(x, yi, z, Nibble4(skyLight, anvilIndex));
                            }
                        }
                    }
                }

                NbtList entities      = dataTag["Entities"] as NbtList;
                NbtList blockEntities = dataTag["TileEntities"] as NbtList;
                if (blockEntities != null)
                {
                    foreach (var nbtTag in blockEntities)
                    {
                        var    blockEntityTag = (NbtCompound)nbtTag;
                        string entityId       = blockEntityTag["id"].StringValue;
                        int    x = blockEntityTag["x"].IntValue;
                        int    y = blockEntityTag["y"].IntValue - yoffset;
                        int    z = blockEntityTag["z"].IntValue;
                        blockEntityTag["y"] = new NbtInt("y", y);

                        BlockEntity blockEntity = BlockEntityFactory.GetBlockEntityById(entityId);
                        if (blockEntity != null)
                        {
                            blockEntityTag.Name = string.Empty;
                            chunk.SetBlockEntity(new BlockCoordinates(x, y, z), blockEntityTag);
                        }
                    }
                }

                NbtList tileTicks = dataTag["TileTicks"] as NbtList;

                chunk.isDirty = false;
                return(chunk);
            }
        }
Exemple #17
0
        public ChunkColumn GenerateChunkColumn(ChunkCoordinates chunkCoordinates)
        {
            lock (_chunkCache)
            {
                ChunkColumn cachedChunk;
                if (_chunkCache.TryGetValue(chunkCoordinates, out cachedChunk))
                {
                    return(cachedChunk);
                }

                ChunkColumn chunk = new ChunkColumn();
                chunk.x = chunkCoordinates.X;
                chunk.z = chunkCoordinates.Z;

                int h = PopulateChunk(chunk);

                chunk.SetBlock(0, h + 1, 0, 7);
                chunk.SetBlock(1, h + 1, 0, 41);
                chunk.SetBlock(2, h + 1, 0, 41);
                chunk.SetBlock(3, h + 1, 0, 41);
                chunk.SetBlock(3, h + 1, 0, 41);

                //chunk.SetBlock(6, h + 1, 6, 57);

                chunk.SetBlock(6, h, 9, 63);
                chunk.SetMetadata(6, h, 9, 12);
                var blockEntity = GetBlockEntity((chunkCoordinates.X * 16) + 6, h, (chunkCoordinates.Z * 16) + 9);
                chunk.SetBlockEntity(blockEntity.Coordinates, blockEntity.GetCompound());

                if (chunkCoordinates.X == 1 && chunkCoordinates.Z == 1)
                {
                    for (int x = 0; x < 10; x++)
                    {
                        for (int z = 0; z < 10; z++)
                        {
                            for (int y = h - 2; y < h; y++)
                            {
                                chunk.SetBlock(x, y, z, 8);
                            }
                        }
                    }
                }

                if (chunkCoordinates.X == 3 && chunkCoordinates.Z == 1)
                {
                    for (int x = 0; x < 10; x++)
                    {
                        for (int z = 0; z < 10; z++)
                        {
                            for (int y = h - 1; y < h; y++)
                            {
                                chunk.SetBlock(x, y, z, 10);
                            }
                        }
                    }
                }

                for (int x = 0; x < 16; x++)
                {
                    for (int z = 0; z < 16; z++)
                    {
                        for (int y = 127; y != 0; y--)
                        {
                            if (chunk.GetBlock(x, y, z) == 0x00)
                            {
                                chunk.SetSkylight(x, y, z, 0xff);
                            }
                            else
                            {
                                chunk.SetSkylight(x, y, z, 0x00);
                            }
                        }
                    }
                }

                // Cache
                chunk.GetBatch();
                _chunkCache[chunkCoordinates] = chunk;

                return(chunk);
            }
        }
Exemple #18
0
        public static ChunkColumn GetChunk(ChunkCoordinates coordinates, string basePath, IWorldProvider generator, int yoffset)
        {
            int width = 32;
            int depth = 32;

            int rx = coordinates.X >> 5;
            int rz = coordinates.Z >> 5;

            string filePath = Path.Combine(basePath, string.Format(@"region{2}r.{0}.{1}.mca", rx, rz, Path.DirectorySeparatorChar));

            if (!File.Exists(filePath))
            {
                return(generator?.GenerateChunkColumn(coordinates));
                //return new ChunkColumn
                //{
                //	x = coordinates.X,
                //	z = coordinates.Z,
                //};
            }

            using (var regionFile = File.OpenRead(filePath))
            {
                byte[] buffer = new byte[8192];

                regionFile.Read(buffer, 0, 8192);

                int xi = (coordinates.X % width);
                if (xi < 0)
                {
                    xi += 32;
                }
                int zi = (coordinates.Z % depth);
                if (zi < 0)
                {
                    zi += 32;
                }
                int tableOffset = (xi + zi * width) * 4;

                regionFile.Seek(tableOffset, SeekOrigin.Begin);

                byte[] offsetBuffer = new byte[4];
                regionFile.Read(offsetBuffer, 0, 3);
                Array.Reverse(offsetBuffer);
                int offset = BitConverter.ToInt32(offsetBuffer, 0) << 4;

                int length = regionFile.ReadByte();

                if (offset == 0 || length == 0)
                {
                    return(generator?.GenerateChunkColumn(coordinates));
                    //return new ChunkColumn
                    //{
                    //	x = coordinates.X,
                    //	z = coordinates.Z,
                    //};
                }

                regionFile.Seek(offset, SeekOrigin.Begin);
                byte[] waste = new byte[4];
                regionFile.Read(waste, 0, 4);
                int compressionMode = regionFile.ReadByte();

                var nbt = new NbtFile();
                nbt.LoadFromStream(regionFile, NbtCompression.ZLib);

                NbtTag dataTag = nbt.RootTag["Level"];

                NbtList sections = dataTag["Sections"] as NbtList;

                ChunkColumn chunk = new ChunkColumn
                {
                    x       = coordinates.X,
                    z       = coordinates.Z,
                    biomeId = dataTag["Biomes"].ByteArrayValue
                };

                for (int i = 0; i < chunk.biomeId.Length; i++)
                {
                    if (chunk.biomeId[i] > 22)
                    {
                        chunk.biomeId[i] = 0;
                    }
                }
                if (chunk.biomeId.Length > 256)
                {
                    throw new Exception();
                }

                // This will turn into a full chunk column
                foreach (NbtTag sectionTag in sections)
                {
                    int    sy      = sectionTag["Y"].ByteValue * 16;
                    byte[] blocks  = sectionTag["Blocks"].ByteArrayValue;
                    byte[] data    = sectionTag["Data"].ByteArrayValue;
                    NbtTag addTag  = sectionTag["Add"];
                    byte[] adddata = new byte[2048];
                    if (addTag != null)
                    {
                        adddata = addTag.ByteArrayValue;
                    }
                    byte[] blockLight = sectionTag["BlockLight"].ByteArrayValue;
                    byte[] skyLight   = sectionTag["SkyLight"].ByteArrayValue;

                    for (int x = 0; x < 16; x++)
                    {
                        for (int z = 0; z < 16; z++)
                        {
                            for (int y = 0; y < 16; y++)
                            {
                                int yi = sy + y - yoffset;
                                if (yi < 0 || yi >= 128)
                                {
                                    continue;
                                }

                                int anvilIndex = y * 16 * 16 + z * 16 + x;
                                int blockId    = blocks[anvilIndex] + (Nibble4(adddata, anvilIndex) << 8);

                                Func <int, byte, byte> dataConverter = (i, b) => b;
                                // Anvil to PE friendly converstion
                                if (Convert.ContainsKey(blockId))
                                {
                                    dataConverter = Convert[blockId].Item2;
                                    blockId       = Convert[blockId].Item1;
                                }
                                else if (Ignore.BinarySearch(blockId) >= 0)
                                {
                                    blockId = 0;
                                }
                                else if (Gaps.BinarySearch(blockId) >= 0)
                                {
                                    Log.WarnFormat("Missing material on convert: {0}", blockId);
                                    blockId = 133;
                                }

                                if (blockId > 255)
                                {
                                    blockId = 41;
                                }

                                //if (yi == 127 && blockId != 0) blockId = 30;
                                if (yi == 0 && (blockId == 8 || blockId == 9))
                                {
                                    blockId = 7;
                                }

                                chunk.SetBlock(x, yi, z, (byte)blockId);
                                byte metadata = Nibble4(data, anvilIndex);
                                metadata = dataConverter(blockId, metadata);

                                chunk.SetMetadata(x, yi, z, metadata);
                                chunk.SetBlocklight(x, yi, z, Nibble4(blockLight, anvilIndex));
                                chunk.SetSkylight(x, yi, z, Nibble4(skyLight, anvilIndex));

                                var block = BlockFactory.GetBlockById(chunk.GetBlock(x, yi, z));
                                if (block is BlockStairs || block is StoneSlab || block is WoodSlab)
                                {
                                    chunk.SetSkylight(x, yi, z, 0xff);
                                }

                                if (blockId == 43 && chunk.GetMetadata(x, yi, z) == 7)
                                {
                                    chunk.SetMetadata(x, yi, z, 6);
                                }
                                else if (blockId == 44 && chunk.GetMetadata(x, yi, z) == 7)
                                {
                                    chunk.SetMetadata(x, yi, z, 6);
                                }
                                else if (blockId == 44 && chunk.GetMetadata(x, yi, z) == 15)
                                {
                                    chunk.SetMetadata(x, yi, z, 14);
                                }
                                else if (blockId == 3 && chunk.GetMetadata(x, yi, z) == 1)
                                {
                                    chunk.SetBlock(x, yi, z, 198);
                                    chunk.SetMetadata(x, yi, z, 0);
                                }
                                else if (blockId == 3 && chunk.GetMetadata(x, yi, z) == 2)
                                {
                                    chunk.SetBlock(x, yi, z, 143);                                     //Coarse Dirt => Pat
                                    chunk.SetMetadata(x, yi, z, 0);                                    // Podzol => (Podzol)
                                }
                            }
                        }
                    }
                }

                NbtList entities      = dataTag["Entities"] as NbtList;
                NbtList blockEntities = dataTag["TileEntities"] as NbtList;
                if (blockEntities != null)
                {
                    foreach (var nbtTag in blockEntities)
                    {
                        var    blockEntityTag = (NbtCompound)nbtTag.Clone();
                        string entityId       = blockEntityTag["id"].StringValue;
                        int    x = blockEntityTag["x"].IntValue;
                        int    y = blockEntityTag["y"].IntValue - yoffset;
                        int    z = blockEntityTag["z"].IntValue;
                        blockEntityTag["y"] = new NbtInt("y", y);

                        BlockEntity blockEntity = BlockEntityFactory.GetBlockEntityById(entityId);
                        if (blockEntity != null)
                        {
                            blockEntityTag.Name = string.Empty;

                            if (blockEntity is Sign)
                            {
                                // Remove the JSON stuff and get the text out of extra data.
                                // TAG_String("Text2"): "{"extra":["10c a loaf!"],"text":""}"
                                CleanSignText(blockEntityTag, "Text1");
                                CleanSignText(blockEntityTag, "Text2");
                                CleanSignText(blockEntityTag, "Text3");
                                CleanSignText(blockEntityTag, "Text4");
                            }

                            chunk.SetBlockEntity(new BlockCoordinates(x, y, z), blockEntityTag);
                        }
                    }
                }

                //NbtList tileTicks = dataTag["TileTicks"] as NbtList;

                chunk.isDirty = false;
                return(chunk);
            }
        }