예제 #1
0
        protected void GenerateLeaves(ChunkColumn world, int x, int y, int z, float size, float width, byte leafBlockId, byte leafMeta, byte woodId, byte woodMeta)
        {
            float dist;
            int   i, j, k, s = (int)(size - 1f), w = (int)((size - 1f) * width);

            for (i = -w; i <= w; i++)
            {
                for (j = -s; j <= s; j++)
                {
                    for (k = -w; k <= w; k++)
                    {
                        dist = Math.Abs((float)i / width) + (float)Math.Abs(j) + Math.Abs((float)k / width);
                        if (dist <= size - 0.5f || (dist <= size && Rnd.NextDouble() < 0.5))
                        {
                            if (dist < 0.6f)
                            {
                                world.SetBlock(x + i, y + j, z + k, woodId);
                                world.SetMetadata(x + i, y + j, z + k, woodMeta);
                            }
                            if (world.GetBlock(x + i, y + j, z + k) == 0)
                            {
                                world.SetBlock(x + i, y + j, z + k, leafBlockId);
                                world.SetMetadata(x + i, y + j, z + k, leafMeta);
                            }
                        }
                    }
                }
            }
        }
예제 #2
0
        protected void GenerateCircle(ChunkColumn chunk, Vector3 location, int radius, byte id, byte meta)
        {
            for (var I = -radius; I <= radius; I = (I + 1))
            {
                for (var j = -radius; j <= radius; j = (j + 1))
                {
                    var max = (int)Math.Sqrt((I * I) + (j * j));
                    if (max <= radius)
                    {
                        var X = location.X + I;
                        var Z = location.Z + j;

                        if (X < 0 || X >= 16 || Z < 0 || Z >= 256)
                        {
                            continue;
                        }

                        var x = (int)X;
                        var y = (int)location.Y;
                        var z = (int)Z;
                        if (chunk.GetBlock(x, y, z).Equals(0))
                        {
                            chunk.SetBlock(x, y, z, id);
                            chunk.SetMetadata(x, y, z, meta);
                        }
                    }
                }
            }
        }
예제 #3
0
        protected void GenerateBranch(ChunkColumn world, float x, float y, float z, double horDir, float verDir, float length, float speed, byte blockId, byte meta)
        {
            if (verDir < 0f)
            {
                verDir = -verDir;
            }

            float c    = 0f;
            float velY = 1f - verDir;

            if (verDir > 1f)
            {
                verDir = 1f - (verDir - 1f);
            }

            float velX = (float)Math.Cos(horDir * Math.PI / 180D) * verDir;
            float velZ = (float)Math.Sin(horDir * Math.PI / 180D) * verDir;

            while (c < length)
            {
                world.SetBlock((int)x, (int)y, (int)z, blockId);
                world.SetMetadata((int)x, (int)y, (int)z, meta);

                x += velX;
                y += velY;
                z += velZ;

                c += speed;
            }
        }
예제 #4
0
        public void SetBlock(Block block)
        {
            ChunkColumn chunk = GetChunk(block.Coordinates);

            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);
        }
예제 #5
0
        public override void Create(ChunkColumn chunk, int x, int y, int z)
        {
            var block = chunk.GetBlock(x, y - 1, z);

            if (block != 2 && block != 3)
            {
                return;
            }

            BaseSize = 3 + Rnd.Next(2);
            if (Roots > 0f)
            {
                for (int k = 0; k < 3; k++)
                {
                    GenerateBranch(chunk, x, y + Roots, z, (120 * k) - 40 + Rnd.Next(80), 1.6f + (float)Rnd.NextDouble() * 0.1f, Roots * 1.7f, 1f, 17, 3);
                }
            }

            for (int i = y + Roots; i < y + BaseSize; i++)
            {
                chunk.SetBlock(x, i, z, 17);
                chunk.SetMetadata(x, i, z, 3);
            }

            float horDir, verDir;
            int   eX, eY, eZ;

            for (int j = 0; j < Branches; j++)
            {
                horDir = (120 * j) - 60 + Rnd.Next(120);
                verDir = VerticalStart + (float)Rnd.NextDouble() * VerticalRand;

                eX = x + (int)(Math.Cos(horDir * Math.PI / 180D) * verDir * BranchLength);
                eZ = z + (int)(Math.Sin(horDir * Math.PI / 180D) * verDir * BranchLength);
                eY = y + BaseSize + (int)((1f - verDir) * BranchLength);

                if (CanGenerateBranch(x, y + BaseSize, z, horDir, verDir, BranchLength, 1f, 4f, 1.5f) && CanGenerateLeaves(eX, eY, eZ, 4f, 1.5f))
                {
                    GenerateBranch(chunk, x, y + BaseSize, z, horDir, verDir, BranchLength, 1f, 17, 3);

                    for (int m = 0; m < 1; m++)
                    {
                        GenerateLeaves(chunk, eX, eY, eZ, 4f, 1.5f, 18, 3, 17, 3);
                    }
                }
            }

            /*var location = new Vector3(x, y, z);
             * if (!ValidLocation(location, 2)) return;
             *
             * int height = Math.Max(4, Rnd.Next(MaxHeight));
             *
             * GenerateColumn(chunk, location, height, 17, 3);
             * Vector3 leafLocation = location + new Vector3(0, height, 0);
             * GenerateVanillaLeaves(chunk, leafLocation, 2, 18, 3);
             */
            //	base.Create(chunk, x, y, z);
        }
예제 #6
0
        public override void Create(ChunkColumn chunk, int x, int y, int z)
        {
            if (x < 6 || x > 10 || z < 6 || z > 10)
            {
                return;
            }

            var block = chunk.GetBlock(x, y - 1, z);

            if (block != 2 && block != 3)
            {
                return;
            }

            BaseSize = 9 + Rnd.Next(5);

            if (Roots > 0f)
            {
                for (int k = 0; k < 3; k++)
                {
                    GenerateBranch(chunk, x, y + Roots, z, (120 * k) - 40 + Rnd.Next(80), 1.6f + (float)Rnd.NextDouble() * 0.1f, Roots * 1.7f, 1f,
                                   17, 3);              //17 = Wood, 3 = Jungle Type
                }
            }

            for (int i = y + Roots; i < y + BaseSize; i++)
            {
                chunk.SetBlock(x, i, z, 17);
                chunk.SetMetadata(x, i, z, 3);
            }

            float horDir, verDir;
            int   eX, eY, eZ;

            for (int j = 0; j < Branches; j++)
            {
                horDir = (120 * j) - 60 + Rnd.Next(120);
                verDir = VerticalStart + (float)Rnd.NextDouble() * VerticalRand;

                eX = x + (int)(Math.Cos(horDir * Math.PI / 180D) * verDir * BranchLength);
                eZ = z + (int)(Math.Sin(horDir * Math.PI / 180D) * verDir * BranchLength);
                eY = y + BaseSize + (int)((1f - verDir) * BranchLength);

                if (CanGenerateBranch(x, y + BaseSize, z, horDir, verDir, BranchLength, 1f, 4f, 1.5f) && CanGenerateLeaves(eX, eY, eZ, 4f, 1.5f))
                {
                    GenerateBranch(chunk, x, y + BaseSize, z, horDir, verDir, BranchLength, 1f,
                                   17, 3);              //17 = Wood, 3 = Jungle Type

                    for (int m = 0; m < 1; m++)
                    {
                        GenerateLeaves(chunk, eX, eY, eZ, 4f, 1.5f,
                                       18, 3,                  //18 = Leaves, 3 = Jungle Type
                                       17, 3);                 //17 = Wood, 3 = Jungle Type
                    }
                }
            }
        }
예제 #7
0
		public void Create(ChunkColumn chunk, int x, int y, int z)
		{
			if (chunk.GetBlock(x, y + MaxHeight, z) == (byte) Material.Air)
			{
				foreach (Block b in Blocks)
				{
					chunk.SetBlock(x + b.Coordinates.X, y + b.Coordinates.Y, z + b.Coordinates.Z, b.Id);
					chunk.SetMetadata(x + b.Coordinates.X, y + b.Coordinates.Y, z + b.Coordinates.Z, b.Metadata);
				}
			}
		}
예제 #8
0
 public static void GenerateColumn(ChunkColumn chunk, Vector3 location, int height, byte id, byte meta)
 {
     for (var o = 0; o < height; o++)
     {
         var x = (int)location.X;
         var y = (int)location.Y + o;
         var z = (int)location.Z;
         chunk.SetBlock(x, y, z, id);
         chunk.SetMetadata(x, y, z, meta);
     }
 }
예제 #9
0
 public void Create(ChunkColumn chunk, int x, int y, int z)
 {
     if (chunk.GetBlock(x, y + MaxHeight, z) == (byte)Material.Air)
     {
         foreach (Block b in Blocks)
         {
             chunk.SetBlock(x + b.Coordinates.X, y + b.Coordinates.Y, z + b.Coordinates.Z, b.Id);
             chunk.SetMetadata(x + b.Coordinates.X, y + b.Coordinates.Y, z + b.Coordinates.Z, b.Metadata);
         }
     }
 }
예제 #10
0
        private void DecorateChunk(ChunkColumn chunk, float[] heightMap, float[] thresholdMap, Biome[] biomes,
                                   ChunkDecorator[] decorators)
        {
            for (int x = 0; x < Width; x++)
            {
                for (int z = 0; z < Depth; z++)
                {
                    var height = chunk.height[(x << 4) + z];
                    var biome  = biomes[(x << 4) + z];

                    for (int y = 0; y < Height; y++)
                    {
                        bool isSurface = false;
                        if (y <= height)
                        {
                            if (y < 255 && chunk.GetBlock(x, y, z) == 1 && chunk.GetBlock(x, y + 1, z) == 0)
                            {
                                isSurface = true;
                            }

                            if (isSurface)
                            {
                                if (y >= WaterLevel)
                                {
                                    chunk.SetBlock(x, y, z, biome.SurfaceBlock);
                                    chunk.SetMetadata(x, y, z, biome.SurfaceMetadata);

                                    chunk.SetBlock(x, y - 1, z, biome.SoilBlock);
                                    chunk.SetMetadata(x, y - 1, z, biome.SoilMetadata);
                                }
                            }
                        }

                        for (int i = 0; i < decorators.Length; i++)
                        {
                            decorators[i].Decorate(chunk, biome, thresholdMap, x, y, z, isSurface, y < height - 1);
                        }
                    }
                }
            }
        }
예제 #11
0
        protected void GenerateTopper(ChunkColumn chunk, Vector3 location, byte type = 0x0)
        {
            var sectionRadius = 1;

            GenerateCircle(chunk, location, sectionRadius, 18, 1);
            var top = location + new Vector3(0, 1, 0);
            var x   = (int)location.X;
            var y   = (int)location.Y + 1;
            var z   = (int)location.Z;

            chunk.SetBlock(x, y, z, 18);
            chunk.SetMetadata(x, y, z, 1);
            if (type == 0x1 && y < 256)
            {
                GenerateVanillaCircle(chunk, new Vector3(x, y, z), sectionRadius, 18, 1);
            }
        }
예제 #12
0
        public override void Create(ChunkColumn chunk, int x, int y, int z)
        {
            if (chunk.GetBlock(x, y - 1, z) != 12)
            {
                return;                                                //Not sand, do not generate.
            }
            var growth = Rnd.Next(0x1, 0x15);

            for (int modifiedY = y; modifiedY < y + _height; modifiedY++)
            {
                if (!CheckSafe(chunk, x, modifiedY, z))
                {
                    break;
                }

                chunk.SetBlock(x, modifiedY, z, 81);                 //Cactus block
                chunk.SetMetadata(x, modifiedY, z, (byte)growth);
            }
        }
예제 #13
0
        protected void GenerateVanillaCircle(ChunkColumn chunk, Vector3 location, int radius, byte id, byte meta,
                                             double corner = 0)
        {
            for (var I = -radius; I <= radius; I = (I + 1))
            {
                for (var j = -radius; j <= radius; j = (j + 1))
                {
                    var max = (int)Math.Sqrt((I * I) + (j * j));
                    if (max <= radius)
                    {
                        if (I.Equals(-radius) && j.Equals(-radius) || I.Equals(-radius) && j.Equals(radius) ||
                            I.Equals(radius) && j.Equals(-radius) || I.Equals(radius) && j.Equals(radius))
                        {
                            if (corner + radius * 0.2 < 0.4 || corner + radius * 0.2 > 0.7 || corner.Equals(0))
                            {
                                continue;
                            }
                        }
                        var x = location.X + I;
                        var z = location.Z + j;
                        if (x < 0 || z > 16)
                        {
                            continue;
                        }
                        if (z < 0 || z > 16)
                        {
                            continue;
                        }

                        if (chunk.GetBlock((int)x, (int)location.Y, (int)z) == 0)
                        {
                            chunk.SetBlock((int)x, (int)location.Y, (int)z, id);
                            chunk.SetMetadata((int)x, (int)location.Y, (int)z, meta);
                        }
                    }
                }
            }
        }
예제 #14
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 < 128; 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 < 127; y++)
                    {
                        //the overhang
                        byte thisblock = chunk.GetBlock(x, y, z);
                        byte 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 < 127; y++)
                    {
                        byte thisblock = chunk.GetBlock(x, y, z);
                        byte 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);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #15
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;
            }

            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);
                        }
                    }
                }
            }
        }
예제 #16
0
        public ChunkColumn GenerateChunkColumn(ChunkCoordinates chunkCoordinates)
        {
            ChunkColumn chunk = new ChunkColumn();

            chunk.x = chunkCoordinates.X;
            chunk.z = chunkCoordinates.Z;

            int xOffset = chunk.x << 4;
            int zOffset = chunk.z << 4;

            for (int x = 0; x < 16; x++)
            {
                for (int z = 0; z < 16; z++)
                {
                    for (int y = 0; y < PlotHeight + 1; y++)
                    {
                        if (y == 0)
                        {
                            chunk.SetBlock(x, y, z, 7);                                 // Bedrock
                        }
                        else if (y == PlotHeight - 1)
                        {
                            chunk.SetBlock(x, y, z, 2);                                                   // grass
                        }
                        else if (y == PlotHeight)
                        {
                            if (!IsZRoad(z + zOffset, true) && !IsXRoad(x + xOffset, true))
                            {
                                var block = PlotPattern.Next(new BlockCoordinates(x, PlotHeight, z));
                                chunk.SetBlock(x, y, z, block.Id);                                 // grass
                                if (block.Metadata != 0)
                                {
                                    chunk.SetMetadata(x, y, z, block.Metadata);                                     // grass
                                }
                            }
                        }
                        else if (y > PlotHeight - 4)
                        {
                            chunk.SetBlock(x, y, z, 3);                                                  // dirt
                        }
                        else
                        {
                            chunk.SetBlock(x, y, z, 1);                          // stone
                        }
                    }
                    chunk.SetHeight(x, z, PlotHeight);
                }
            }


            var leaves = new Leaves();

            //if (xOffset < 0) xOffset -= PlotAreaWidth;
            //if (zOffset < 0) zOffset -= PlotAreaDepth;

            for (int x = xOffset; x < xOffset + 16; x++)
            {
                for (int z = zOffset; z < zOffset + 16; z++)
                {
                    for (int i = 1; i < RoadWidth - 1; i++)
                    {
                        var block = RoadPattern.Next(new BlockCoordinates(x, PlotHeight, z));
                        if ((x - i) % PlotAreaWidth == 0)
                        {
                            chunk.SetBlock(x - xOffset, PlotHeight - 1, z - zOffset, block.Id);
                            if (block.Metadata != 0)
                            {
                                chunk.SetMetadata(x - xOffset, PlotHeight - 1, z - zOffset, block.Metadata);
                            }
                        }
                        if ((z - i) % PlotAreaDepth == 0)
                        {
                            chunk.SetBlock(x - xOffset, PlotHeight - 1, z - zOffset, block.Id);
                            if (block.Metadata != 0)
                            {
                                chunk.SetMetadata(x - xOffset, PlotHeight - 1, z - zOffset, block.Metadata);
                            }
                        }
                    }

                    if (x % PlotAreaWidth == 0 && !IsZRoad(z))
                    {
                        chunk.SetBlock(x - xOffset, PlotHeight, z - zOffset, leaves.Id);
                    }
                    if ((x - RoadWidth + 1) % PlotAreaWidth == 0 && !IsZRoad(z))
                    {
                        chunk.SetBlock(x - xOffset, PlotHeight, z - zOffset, leaves.Id);
                    }

                    if (z % PlotAreaDepth == 0 && !IsXRoad(x))
                    {
                        chunk.SetBlock(x - xOffset, PlotHeight, z - zOffset, leaves.Id);
                    }
                    if ((z - RoadWidth + 1) % PlotAreaDepth == 0 && !IsXRoad(x))
                    {
                        chunk.SetBlock(x - xOffset, PlotHeight, z - zOffset, leaves.Id);
                    }

                    if (x % PlotAreaWidth == 0 && z % PlotAreaDepth == 0)
                    {
                        chunk.SetBlock(x - xOffset, PlotHeight + 1, z - zOffset, new RedstoneBlock().Id);
                    }
                    if (x % PlotAreaWidth == PlotAreaWidth - 1 && z % PlotAreaDepth == PlotAreaDepth - 1)
                    {
                        chunk.SetBlock(x - xOffset, PlotHeight + 1, z - zOffset, new LapisBlock().Id);                                                                                                   // stone
                    }
                }
            }

            return(chunk);
        }
예제 #17
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;
            }
        }
예제 #18
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);
                            }
                        }
                    }
                }

                _chunkCache[chunkCoordinates] = chunk;

                return chunk;
            }
        }
예제 #19
0
        public override void Decorate(ChunkColumn column, Biome biome, float[] thresholdMap, int x, int y, int z, bool surface,
                                      bool isBelowMaxHeight)
        {
            try
            {
                var currentTemperature = biome.Temperature;
                if (y > 64)
                {
                    int distanceToSeaLevel = y - 64;
                    currentTemperature = biome.Temperature - (0.00166667f * distanceToSeaLevel);
                }

                int rx = column.x * 16 + x;
                int rz = column.z * 16 + z;

                bool generated = false;
                if (surface && y >= OverworldGenerator.WaterLevel)
                {
                    var noise = Simplex.Noise(rx, rz, biome.Downfall, 0.5, true);
                    if (x >= 3 && x <= 13 && z >= 3 && z <= 13)
                    {
                        Structure tree = null;
                        if (biome.Downfall <= 0f && biome.Temperature >= 2f)
                        {
                            if (GetRandom(32) == 16)
                            {
                                var randValue = GetRandom(18);
                                if (randValue >= 0 && randValue <= 2)                                 //3 tall cactus
                                {
                                    tree = new CactusStructure(3);
                                }
                                else if (randValue > 2 && randValue <= 5)                                 // 2 tall cactus
                                {
                                    tree = new CactusStructure(2);
                                }
                                else if (randValue > 5 && randValue <= 11)                                 // 1 tall cactus
                                {
                                    tree = new CactusStructure(1);
                                }
                            }
                        }

                        if (tree == null && biome.Downfall >= 0 && (noise > ((1f - biome.Downfall) /* + 0.5*/) + (y / 512f)))
                        {
                            if (currentTemperature >= 1f && biome.Downfall >= 0.2f)
                            {
                                if (GetRandom(8) == 4)
                                {
                                    tree = new LargeJungleTree();
                                }
                                else
                                {
                                    tree = new SmallJungleTree();
                                }
                            }

                            /*	else if (currentTemperature >= 0.7F && biome.Downfall >= 0.2f)
                             *      {
                             *              tree = new OakTree(true);
                             *      }*/
                            else if (currentTemperature >= 0.7F && biome.Downfall < 0.2f)
                            {
                                tree = new AcaciaTree();
                            }
                            else if (currentTemperature > 0.25f && biome.Downfall > 0f)
                            {
                                if (biome.Name.Contains("Birch") || GetRandom(16) == 8)
                                {
                                    tree = new BirchTree();
                                }
                                else
                                {
                                    tree = new OakTree();
                                }
                            }
                            else if (currentTemperature <= 0.25f && biome.Downfall > 0f)
                            {
                                tree = new PineTree();
                            }
                        }

                        if (tree != null)
                        {
                            if (y + 1 < 254)
                            {
                                tree.Create(column, x, y + 1, z);
                            }
                            generated = true;
                        }
                    }

                    if (!generated)
                    {
                        if (noise > 0.5)                         //Threshold 1
                        {
                            /*if (currentTemperature > 0.3f && currentTemperature < 1.5f && biome.Downfall >= 0.85f)
                             * {
                             *      column.SetBlock(x, y + 1, z, 18); //Leaves
                             *      column.SetMetadata(x, y + 1, z, 3); //Jungle Leaves
                             * }
                             * else*/
                            if (currentTemperature > 0.3f && currentTemperature < 1.5f && biome.Downfall > 0)
                            {
                                var blockBeneath = column.GetBlock(x, y, z);

                                var sugarPosibility = GetRandom(18);
                                if (/*sugarPosibility <= 11*/ noise > 0.75f &&
                                    (blockBeneath == 3 || blockBeneath == 2 || blockBeneath == 12) &&
                                    IsValidSugarCaneLocation(column, x, y, z))
                                {
                                    int height = 1;
                                    if (sugarPosibility <= 2)
                                    {
                                        height = 3;
                                    }
                                    else if (sugarPosibility <= 5)
                                    {
                                        height = 2;
                                    }

                                    //var growth = Rnd.Next(0x1, 0x15);
                                    for (int mY = y + 1; mY < y + 1 + height; mY++)
                                    {
                                        column.SetBlock(x, mY, z, 83);                                         //SugarCane
                                        if (mY == y + 1 + height)
                                        {
                                            column.SetMetadata(x, mY, z, (byte)Rnd.Next(0, 15));
                                        }
                                        else
                                        {
                                            column.SetMetadata(x, mY, z, 0);
                                        }
                                    }
                                }
                                else if (noise > 0.8 && blockBeneath == 3 || blockBeneath == 2)                                 //If above 0.8, we generate flowers :)
                                {
                                    if (Simplex.Noise(rx, rz, 0.5f, 0.5f, true) > 0.5)
                                    {
                                        column.SetBlock(x, y + 1, z, 38);                                         //Poppy
                                        column.SetMetadata(x, y + 1, z, (byte)GetRandom(8));
                                    }
                                    else
                                    {
                                        column.SetBlock(x, y + 1, z, 37);                                         //Dandelion
                                    }
                                }
                                else if (blockBeneath == 3 || blockBeneath == 2)
                                {
                                    column.SetBlock(x, y + 1, z, 31);                                     //Grass
                                    column.SetMetadata(x, y + 1, z, 1);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
            }
        }