Example #1
0
        private static void AddChunk(MinecraftClient client, int x, int z, ushort primaryBitMap, ushort addBitMap, bool lightIncluded, bool groundUp, byte[] data)
        {
            var coordinates = new Coordinates2D(x, z);
            var relativePosition = GetRelativeChunkPosition(coordinates);
            var chunk = new Chunk(relativePosition);
            var sectionCount = GetSectionCount(primaryBitMap);

            // Run through the sections
            // TODO: Support block IDs >255
            for (int y = 0; y < 16; y++)
            {
                if ((primaryBitMap & (1 << y)) > 0)
                {
                    // Blocks
                    Array.Copy(data, y * BlockDataLength, chunk.Sections[y].Blocks, 0, BlockDataLength);
                    // Metadata
                    Array.Copy(data, (BlockDataLength * sectionCount) + (y * NibbleDataLength),
                        chunk.Sections[y].Metadata.Data, 0, NibbleDataLength);
                    // Light
                    Array.Copy(data, ((BlockDataLength + NibbleDataLength) * sectionCount) + (y * NibbleDataLength),
                        chunk.Sections[y].BlockLight.Data, 0, NibbleDataLength);
                    // Sky light
                    if (lightIncluded)
                    {
                        Array.Copy(data, ((BlockDataLength + NibbleDataLength + NibbleDataLength) * sectionCount) + (y * NibbleDataLength),
                            chunk.Sections[y].SkyLight.Data, 0, NibbleDataLength);
                    }
                }
            }
            if (groundUp)
                Array.Copy(data, data.Length - chunk.Biomes.Length, chunk.Biomes, 0, chunk.Biomes.Length);
            client.World.SetChunk(coordinates, chunk);
            //client.OnChunkRecieved(new ChunkRecievedEventArgs(position, new ReadOnlyChunk(chunk)));
        }
Example #2
0
        public void SetChunk(Coordinates2D coordinates, Chunk chunk)
        {
            int regionX = coordinates.X / Region.Width - ((coordinates.X < 0) ? 1 : 0);
            int regionZ = coordinates.Z / Region.Depth - ((coordinates.Z < 0) ? 1 : 0);

            var region = LoadOrGenerateRegion(new Coordinates2D(regionX, regionZ));
            lock (region)
            {
                chunk.IsModified = true;
                region.SetChunk(new Coordinates2D(coordinates.X - regionX * 32, coordinates.Z - regionZ * 32), chunk);
            }
        }
 public Chunk GenerateChunk(Coordinates2D position)
 {
     var chunk = new Chunk(position);
     int y = 0;
     for (int i = 0; i < Layers.Count; i++)
     {
         int height = y + Layers[i].Height;
         while (y < height)
         {
             for (int x = 0; x < 16; x++)
             {
                 for (int z = 0; z < 16; z++)
                 {
                     chunk.SetBlockId(new Coordinates3D(x, y, z), Layers[i].BlockId);
                     chunk.SetMetadata(new Coordinates3D(x, y, z), Layers[i].Metadata);
                 }
             }
             y++;
         }
     }
     for (int i = 0; i < chunk.Biomes.Length; i++)
         chunk.Biomes[i] = (byte)Biome;
     return chunk;
 }
Example #4
0
        public Coordinates3D FindBlockPosition(Coordinates3D coordinates, out Chunk chunk)
        {
            if (coordinates.Y < 0 || coordinates.Y >= Chunk.Height)
                throw new ArgumentOutOfRangeException("coordinates", "Coordinates are out of range");

            var chunkX = (int)Math.Floor((double)coordinates.X / Chunk.Width);
            var chunkZ = (int)Math.Floor((double)coordinates.Z / Chunk.Depth);

            chunk = GetChunk(new Coordinates2D(chunkX, chunkZ));
            return new Coordinates3D(
                (coordinates.X - chunkX * Chunk.Width) % Chunk.Width,
                coordinates.Y,
                (coordinates.Z - chunkZ * Chunk.Depth) % Chunk.Depth);
        }
Example #5
0
 internal ReadOnlyChunk(Chunk chunk)
 {
     Chunk = chunk;
 }
Example #6
0
 internal void SetChunk(Coordinates2D coordinates, Chunk chunk)
 {
     World.SetChunk(coordinates, chunk);
 }
Example #7
0
 /// <summary>
 /// Sets the chunk at the specified local position to the given value.
 /// </summary>
 public void SetChunk(Coordinates2D position, Chunk chunk)
 {
     if (!Chunks.ContainsKey(position))
         Chunks.Add(position, chunk);
     chunk.IsModified = true;
     chunk.X = position.X;
     chunk.Z = position.Z;
     chunk.LastAccessed = DateTime.Now;
     Chunks[position] = chunk;
 }
Example #8
0
        /// <summary>
        /// Generates a chunk by getting an array of heights then placing blocks of varying types up to that height
        /// then it adds trees (leaves first then trunk)
        /// 
        /// </summary>
        /// <returns>The chunk.</returns>
        /// <param name="position">Position.</param>
        public Chunk GenerateChunk(Coordinates2D position)
        {
            // TODO: Add Ores
            // TODO: Add Caves
            int trees = new Random().Next(0, 10);
            int[,] heights = new int[16, 16];
            int[,] treeBasePositions = new int[trees, 2];

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

            //Make a new Chunk
            var chunk = new Chunk(position);
            //Loop through all the blocks in the chunk
            for (int x = 0; x < 16; x++)
            {
                for (int z = 0; z < 16; z++)
                {
                    int height = GetHeight(chunk.X * Chunk.Width + x, chunk.Z * Chunk.Depth + z);
                    for (int y = 0; y < height; y++)
                    {
                        if (y == 0) // if at the bottom then set block to bedrock
                            chunk.SetBlockId(new Coordinates3D(x, y, z), 7);
                        else if (y < height - 1) // if not at the top set the block to dirt or stone depending on height
                        {
                            if (!(y < (height / 4) * 3))
                                chunk.SetBlockId(new Coordinates3D(x, y, z), 3);
                            else
                                chunk.SetBlockId(new Coordinates3D(x, y, z), 1);
                        }
                        else if (y < waterLevel) // if below the water set to sand or clay
                        {
                            if (new Random().Next(1, 40) < 5 && y < waterLevel - 4)
                                chunk.SetBlockId(new Coordinates3D(x, y, z), 82);
                            else
                                chunk.SetBlockId(new Coordinates3D(x, y, z), 12);
                        }
                        else
                        {
                            // otherwise set the block to grass or gravel rarely
                            chunk.SetBlockId(new Coordinates3D(x, y, z), 2);
                        }
                        chunk.SetBiome((byte)x, (byte)z, Biome.ExtremeHills);
                        if (y < waterLevel + 17)
                            chunk.SetBiome((byte)x, (byte)z, Biome.ExtremeHillsEdge);
                        if (y < waterLevel + 10)
                            chunk.SetBiome((byte)x, (byte)z, Biome.Beach);
                    }
                    heights[x, z] = height;

                    //create beaches and place water
                    if (height <= waterLevel)
                    {
                        for (int w = 0; w < waterLevel - 3; w++)
                        {
                            if (chunk.GetBlockId(new Coordinates3D(x, w, z)) == 0)
                            {
                                chunk.SetBlockId(new Coordinates3D(x, w, z), 8);
                            }
                        }
                    }

                    // Generate colour of the wood and leaves
                    int woodColor = new Random().Next(1, 3);
                    if (woodColor == 1)
                        woodColor = 0;

                    // Generate trees
                    for (int pos = 0; pos < trees; pos++)
                    {
                        int random = new Random().Next(3, 4);
                        int treeBase = heights[treeBasePositions[pos, 0], treeBasePositions[pos, 1]];//chunk.GetHeight((byte)treeBasePositions[pos, 0], (byte)treeBasePositions[pos, 1]);
                        if (treeBasePositions[pos, 0] < 14 && treeBasePositions[pos, 0] > 4 && treeBasePositions[pos, 1] < 14 && treeBasePositions[pos, 1] > 4)
                        {
                            if (treeBase < waterLevel + 10)
                                break;
                            int leafwidth = 4;
                            for (int layer = 0; layer <= height; layer++)
                            {
                                for (int w = 0; w <= leafwidth; w++)
                                {
                                    for (int l = 0; l <= leafwidth; l++)
                                    {
                                        chunk.SetBlockId(new Coordinates3D(treeBasePositions[pos, 0] - (leafwidth / 2) + w, treeBase + layer + random, treeBasePositions[pos, 1] - (leafwidth / 2) + l), 18);
                                        chunk.SetMetadata(new Coordinates3D(treeBasePositions[pos, 0] - (leafwidth / 2) + w, treeBase + layer + random, treeBasePositions[pos, 1] - (leafwidth / 2) + l), (byte)woodColor);
                                    }
                                }
                                leafwidth -= 1;
                            }

                            for (int t = 0; t <= (random + 2); t++)
                            {
                                chunk.SetBlockId(new Coordinates3D(treeBasePositions[pos, 0], treeBase + t, treeBasePositions[pos, 1]), 17);
                                chunk.SetMetadata(new Coordinates3D(treeBasePositions[pos, 0], treeBase + t, treeBasePositions[pos, 1]), (byte)woodColor);
                            }
                        }
                    }
                }
            }
            return chunk;
        }
Example #9
0
        public static ChunkDataPacket CreatePacket(Chunk chunk)
        {
            var X = chunk.X;
            var Z = chunk.Z;

            byte[] blockData;
            byte[] metadata;
            byte[] blockLight;
            byte[] skyLight;

            ushort mask = 1, chunkY = 0;
            bool nonAir = true;

            // First pass calculates number of sections to send
            int totalSections = 0;
            for (int i = 15; i >= 0; i--)
            {
                Section s = chunk.Sections[chunkY++];

                if (s.IsAir)
                    nonAir = false;
                if (nonAir)
                    totalSections++;
            }

            mask = 1;
            chunkY = 0;
            nonAir = true;
            blockData = new byte[totalSections * BlockDataLength];
            metadata = new byte[totalSections * NibbleDataLength];
            blockLight = new byte[totalSections * NibbleDataLength];
            skyLight = new byte[totalSections * NibbleDataLength];

            ushort PrimaryBitMap = 0, AddBitMap = 0;

            // Second pass produces the arrays
            for (int i = 15; i >= 0; i--)
            {
                Section s = chunk.Sections[chunkY++];

                if (s.IsAir)
                    nonAir = false;
                if (nonAir)
                {
                    Array.Copy(s.Blocks, 0, blockData, (chunkY - 1) * BlockDataLength, BlockDataLength);
                    Array.Copy(s.Metadata.Data, 0, metadata, (chunkY - 1) * NibbleDataLength, NibbleDataLength);
                    Array.Copy(s.BlockLight.Data, 0, blockLight, (chunkY - 1) * NibbleDataLength, NibbleDataLength);
                    Array.Copy(s.SkyLight.Data, 0, skyLight, (chunkY - 1) * NibbleDataLength, NibbleDataLength);

                    PrimaryBitMap |= mask;
                }

                mask <<= 1;
            }

            // Create the final array
            // TODO: Merge this into the other loop, reduce objects
            byte[] data = new byte[blockData.Length + metadata.Length +
                blockLight.Length + skyLight.Length + chunk.Biomes.Length];
            int index = 0;
            Array.Copy(blockData, 0, data, index, blockData.Length);
            index += blockData.Length;
            Array.Copy(metadata, 0, data, index, metadata.Length);
            index += metadata.Length;
            Array.Copy(blockLight, 0, data, index, blockLight.Length);
            index += blockLight.Length;
            Array.Copy(skyLight, 0, data, index, skyLight.Length);
            index += skyLight.Length;
            Array.Copy(chunk.Biomes, 0, data, index, chunk.Biomes.Length);

            // Compress the array
            var result = ZlibStream.CompressBuffer(data);
            var GroundUpContiguous = true;

            return new ChunkDataPacket(X, Z, GroundUpContiguous, PrimaryBitMap, AddBitMap, result);
        }