Ejemplo n.º 1
0
        public async Task <bool> CanTreeGrow(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, int height)
        {
            bool result = true;

            // 检查所有方块可替换
            for (int y = pos.Y; y <= pos.Y + 1 + height; ++y)
            {
                int xzSize = 1;

                // 底端
                if (y == pos.Y)
                {
                    xzSize = 0;
                }

                // 顶端
                if (y >= pos.Y + height - 1)
                {
                    xzSize = 2;
                }

                // 检查这个平面所有方块可替换
                for (int x = pos.X - xzSize; x <= pos.X + xzSize && result; ++x)
                {
                    for (int z = pos.Z - xzSize; z <= pos.Z + xzSize && result; ++z)
                    {
                        if (y >= 0 && y < 256)
                        {
                            var        checkPos = new BlockWorldPos(x, y, z);
                            BlockState state    = await GetBlock(world, chunkWorldPos, checkPos);

                            if (!state.IsAir() &&
                                !state.IsLeaves())
                            {
                                result = false;
                            }
                        }
                        else
                        {
                            result = false;
                        }
                    }
                }
            }

            return(result);
        }
Ejemplo n.º 2
0
        public bool CanTreeGrow(IWorld world, IGrainFactory grainFactory, ChunkColumnCompactStorage chunk, Biome biome, Random random, BlockWorldPos pos, int height)
        {
            bool result = true;

            // 检查所有方块可替换
            for (int y = pos.Y; y <= pos.Y + 1 + height; ++y)
            {
                int xzSize = 1;

                // 底端
                if (y == pos.Y)
                {
                    xzSize = 0;
                }

                // 顶端
                if (y >= pos.Y + height - 1)
                {
                    xzSize = 2;
                }

                // 检查这个平面所有方块可替换
                for (int x = pos.X - xzSize; x <= pos.X + xzSize && result; ++x)
                {
                    for (int z = pos.Z - xzSize; z <= pos.Z + xzSize && result; ++z)
                    {
                        if (y >= 0 && y < 256)
                        {
                            BlockChunkPos chunkPos = pos.ToBlockChunkPos();
                            BlockState    state    = chunk[chunkPos.X, chunkPos.Y, chunkPos.Z];
                            if (!state.IsAir() &&
                                state.IsLeaves())
                            {
                                result = false;
                            }
                        }
                        else
                        {
                            result = false;
                        }
                    }
                }
            }

            return(result);
        }
Ejemplo n.º 3
0
        /**
         * grow leaves in a circle
         */
        protected async Task GrowLeavesLayer(IWorld world, BlockWorldPos layerCenter, int width)
        {
            int i = width * width;

            for (int j = -width; j <= width; ++j)
            {
                for (int k = -width; k <= width; ++k)
                {
                    if (j * j + k * k <= i)
                    {
                        BlockWorldPos blockpos = BlockWorldPos.Add(layerCenter, j, 0, k);
                        BlockState    state    = await world.GetBlockStateUnsafe(this.GrainFactory, blockpos);

                        if (state.IsAir() || state.IsLeaves())
                        {
                            await world.SetBlockStateUnsafe(this.GrainFactory, blockpos, _leaves);
                        }
                    }
                }
            }
        }
Ejemplo n.º 4
0
        public override void Generate(IWorld world, IGrainFactory grainFactory, ChunkColumnStorage chunk, Biome biome, Random random, BlockWorldPos pos)
        {
            int  height = random.Next(4) + 6;
            int  j      = 1 + random.Next(2);
            int  k      = height - j;
            int  l      = 2 + random.Next(2);
            bool flag   = true;

            if (pos.Y >= 1 && pos.Y + height + 1 <= 255)
            {
                for (int y = pos.Y; y <= pos.Y + 1 + height && flag; ++y)
                {
                    int xzWidth;

                    if (y - pos.Y < j)
                    {
                        xzWidth = 0;
                    }
                    else
                    {
                        xzWidth = l;
                    }

                    for (int x = pos.X - xzWidth; x <= pos.X + xzWidth && flag; ++x)
                    {
                        for (int z = pos.Z - xzWidth; z <= pos.Z + xzWidth && flag; ++z)
                        {
                            if (y >= 0 && y < 256)
                            {
                                BlockChunkPos chunkPos = new BlockWorldPos(x, y, z).ToBlockChunkPos();
                                BlockState    state    = chunk[chunkPos.X, chunkPos.Y, chunkPos.Z];

                                if (!(state.IsAir() ||
                                      state.IsLeaves()))
                                {
                                    flag = false;
                                }
                            }
                            else
                            {
                                flag = false;
                            }
                        }
                    }
                }

                if (!flag)
                {
                    // return false;
                }
                else
                {
                    BlockChunkPos down  = new BlockWorldPos(pos.X, pos.Y - 1, pos.Z).ToBlockChunkPos();
                    BlockState    state = chunk[down.X, down.Y, down.Z];

                    if (CanSustainTree(PlantsType.Spruce, state) && pos.Y < 256 - height - 1)
                    {
                        int xzWidth = random.Next(2);
                        int j3      = 1;
                        int k3      = 0;

                        for (int l3 = 0; l3 <= k; ++l3)
                        {
                            int y = pos.Y + height - l3;

                            for (int x = pos.X - xzWidth; x <= pos.X + xzWidth; ++x)
                            {
                                int deltaX = x - pos.X;

                                for (int z = pos.Z - xzWidth; z <= pos.Z + xzWidth; ++z)
                                {
                                    int deltaZ = z - pos.Z;

                                    if (Math.Abs(deltaX) != xzWidth || Math.Abs(deltaZ) != xzWidth || xzWidth <= 0)
                                    {
                                        BlockChunkPos blockpos = new BlockWorldPos(x, y, z).ToBlockChunkPos();
                                        state = chunk[blockpos.X, blockpos.Y, blockpos.Z];

                                        if (state.IsAir() ||
                                            state.IsLeaves() ||
                                            state.IsSameId(BlockStates.Vines()))
                                        {
                                            chunk[blockpos.X, blockpos.Y, blockpos.Z] = _leaves;
                                        }
                                    }
                                }
                            }

                            if (xzWidth >= j3)
                            {
                                xzWidth = k3;
                                k3      = 1;
                                ++j3;

                                if (j3 > l)
                                {
                                    j3 = l;
                                }
                            }
                            else
                            {
                                ++xzWidth;
                            }
                        }

                        int heightLeft = random.Next(3);

                        for (int y = 0; y < height - heightLeft; ++y)
                        {
                            BlockChunkPos upN = new BlockWorldPos(pos.X, pos.Y + y, pos.Z).ToBlockChunkPos();
                            state = chunk[upN.X, upN.Y, upN.Z];

                            if (state.IsAir() || state.IsSameId(BlockStates.Leaves()) || state.IsSameId(BlockStates.Leaves2()))
                            {
                                chunk[upN.X, upN.Y, upN.Z] = _wood;
                            }
                        }

                        // return true;
                    }
                    else
                    {
                        // return false;
                    }
                }
            }
            else
            {
                // return false;
            }
        }
Ejemplo n.º 5
0
        public override void Generate(IWorld world, IGrainFactory grainFactory, ChunkColumnCompactStorage chunk, Biome biome, Random random, BlockWorldPos pos)
        {
            int height       = random.Next(5) + 7;
            int heightLeaves = height - random.Next(2) - 3;
            int k            = height - heightLeaves;
            int l            = 1 + random.Next(k + 1);

            if (pos.Y >= 1 && pos.Y + height + 1 <= 256)
            {
                bool flag = true;

                for (int y = pos.Y; y <= pos.Y + 1 + height && flag; ++y)
                {
                    int xzWidth = 1;

                    if (y - pos.Y < heightLeaves)
                    {
                        xzWidth = 0;
                    }
                    else
                    {
                        xzWidth = l;
                    }

                    for (int x = pos.X - xzWidth; x <= pos.X + xzWidth && flag; ++x)
                    {
                        for (int z = pos.Z - xzWidth; z <= pos.Z + xzWidth && flag; ++z)
                        {
                            if (y >= 0 && y < 256)
                            {
                                BlockChunkPos chunkpos = new BlockWorldPos(x, y, z).ToBlockChunkPos();
                                BlockState    block    = chunk[chunkpos.X, chunkpos.Y, chunkpos.Z];
                                if (!(block.IsAir() ||
                                      block.IsLeaves() ||
                                      block.IsSameId(BlockStates.Vines())))
                                {
                                    flag = false;
                                }
                            }
                            else
                            {
                                flag = false;
                            }
                        }
                    }
                }

                if (!flag)
                {
                    // return false;
                }
                else
                {
                    BlockChunkPos down   = new BlockWorldPos(pos.X, pos.Y - 1, pos.Z).ToBlockChunkPos();
                    BlockState    state  = chunk[down.X, down.Y, down.Z];
                    bool          isSoil = CanSustainTree(PlantsType.Spruce, state);

                    if (isSoil && pos.Y < 256 - height - 1)
                    {
                        int xzWidth = 0;

                        for (int y = pos.Y + height; y >= pos.Y + heightLeaves; --y)
                        {
                            for (int x = pos.X - xzWidth; x <= pos.X + xzWidth; ++x)
                            {
                                int deltaX = x - pos.X;

                                for (int z = pos.Z - xzWidth; z <= pos.Z + xzWidth; ++z)
                                {
                                    int deltaZ = z - pos.Z;

                                    if (Math.Abs(deltaX) != xzWidth || Math.Abs(deltaZ) != xzWidth || xzWidth <= 0)
                                    {
                                        BlockChunkPos blockpos = new BlockWorldPos(x, y, z).ToBlockChunkPos();
                                        state = chunk[blockpos.X, blockpos.Y, blockpos.Z];

                                        if (state.IsAir() ||
                                            state.IsLeaves() ||
                                            state.IsSameId(BlockStates.Vines()))
                                        {
                                            chunk[blockpos.X, blockpos.Y, blockpos.Z] = _leaves;
                                        }
                                    }
                                }
                            }

                            if (xzWidth >= 1 && y == pos.Y + heightLeaves + 1)
                            {
                                --xzWidth;
                            }
                            else if (xzWidth < l)
                            {
                                ++xzWidth;
                            }
                        }

                        for (int y = 0; y < height - 1; ++y)
                        {
                            BlockChunkPos upN = new BlockWorldPos(pos.X, pos.Y + y, pos.Z).ToBlockChunkPos();
                            state = chunk[upN.X, upN.Y, upN.Z];

                            if (state.IsAir() || state.IsLeaves())
                            {
                                chunk[upN.X, upN.Y, upN.Z] = _wood;
                            }
                        }

                        // return true;
                    }
                    else
                    {
                        // return false;
                    }
                }
            }
            else
            {
                // return false;
            }
        }
 public static bool IsReplaceable(BlockState state)
 {
     return(state.IsAir() || state.IsLeaves() || state.IsWood());
 }
Ejemplo n.º 7
0
        private async Task <bool> GenerateImpl(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, Random rand)
        {
            int  height = rand.Next(3) + rand.Next(3) + 5;
            bool flag   = true;

            if (pos.Y >= 1 && pos.Y + height + 1 <= 256)
            {
                // check if enough space
                for (int y = pos.Y; y <= pos.Y + 1 + height; ++y)
                {
                    int xzRange = 1;

                    if (y == pos.Y)
                    {
                        xzRange = 0;
                    }

                    if (y >= pos.Y + 1 + height - 2)
                    {
                        xzRange = 2;
                    }

                    for (int xOffset = pos.X - xzRange; xOffset <= pos.X + xzRange && flag; ++xOffset)
                    {
                        for (int zOffset = pos.Z - xzRange; zOffset <= pos.Z + xzRange && flag; ++zOffset)
                        {
                            if (y >= 0 && y < 256)
                            {
                                var blockState = await world.GetBlockStateUnsafe(this.GrainFactory, new BlockWorldPos(xOffset, y, zOffset));

                                if (!IsReplaceable(blockState))
                                {
                                    flag = false;
                                }
                            }
                            else
                            {
                                flag = false;
                            }
                        }
                    }
                }

                // plant tree
                if (!flag)
                {
                    return(false);
                }
                else
                {
                    BlockWorldPos down  = pos.Down();
                    BlockState    state = await world.GetBlockStateUnsafe(this.GrainFactory, down);

                    bool isSoil = IsSoil(state);

                    if (isSoil && pos.Y < ChunkConstants.ChunkHeight - height - 1)
                    {
                        // state.getBlock().onPlantGrow(state, world, down, pos);
                        Facing enumfacing   = Facing.RadomFacing(rand, Plane.XZ);
                        int    bendingPos   = height - rand.Next(4) - 1;
                        int    l2           = 3 - rand.Next(3);
                        int    woodX        = pos.X;
                        int    woodZ        = pos.Z;
                        int    branchHeight = 0;

                        for (int yOffset = 0; yOffset < height; ++yOffset)
                        {
                            int curHeight = pos.Y + yOffset;

                            if (yOffset >= bendingPos && l2 > 0)
                            {
                                woodX += enumfacing.ToBlockVector().X;
                                woodZ += enumfacing.ToBlockVector().Z;
                                --l2;
                            }

                            BlockWorldPos blockpos = new BlockWorldPos(woodX, curHeight, woodZ);
                            state = await world.GetBlockStateUnsafe(this.GrainFactory, blockpos);

                            if (state.IsAir() || state.IsLeaves())
                            {
                                await world.SetBlockStateUnsafe(this.GrainFactory, blockpos, _wood);

                                branchHeight = curHeight;
                            }
                        }

                        BlockWorldPos blockpos2 = new BlockWorldPos(woodX, branchHeight, woodZ);

                        for (int xOffset = -3; xOffset <= 3; ++xOffset)
                        {
                            for (int zOffset = -3; zOffset <= 3; ++zOffset)
                            {
                                if (Math.Abs(xOffset) != 3 || Math.Abs(zOffset) != 3)
                                {
                                    await world.SetBlockStateUnsafe(this.GrainFactory, BlockWorldPos.Add(blockpos2, xOffset, 0, zOffset), _leaves);
                                }
                            }
                        }

                        blockpos2 = blockpos2.Up();

                        for (int xOffset = -1; xOffset <= 1; ++xOffset)
                        {
                            for (int zOffset = -1; zOffset <= 1; ++zOffset)
                            {
                                await world.SetBlockStateUnsafe(this.GrainFactory, BlockWorldPos.Add(blockpos2, xOffset, 0, zOffset), _leaves);
                            }
                        }

                        await world.SetBlockStateUnsafe(this.GrainFactory, blockpos2.East(2), _leaves);

                        await world.SetBlockStateUnsafe(this.GrainFactory, blockpos2.West(2), _leaves);

                        await world.SetBlockStateUnsafe(this.GrainFactory, blockpos2.South(2), _leaves);

                        await world.SetBlockStateUnsafe(this.GrainFactory, blockpos2.North(2), _leaves);

                        woodX = pos.X;
                        woodZ = pos.Z;
                        Facing enumfacing1 = Facing.RadomFacing(rand, Plane.XZ);

                        if (enumfacing1 != enumfacing)
                        {
                            int l3 = bendingPos - rand.Next(2) - 1;
                            int k4 = 1 + rand.Next(3);
                            branchHeight = 0;

                            for (int l4 = l3; l4 < height && k4 > 0; --k4)
                            {
                                if (l4 >= 1)
                                {
                                    int j2 = pos.Y + l4;
                                    woodX += enumfacing1.ToBlockVector().X;
                                    woodZ += enumfacing1.ToBlockVector().Z;
                                    BlockWorldPos blockpos1 = new BlockWorldPos(woodX, j2, woodZ);
                                    state = await world.GetBlockStateUnsafe(this.GrainFactory, blockpos1);

                                    if (state.IsAir() || state.IsLeaves())
                                    {
                                        await world.SetBlockStateUnsafe(this.GrainFactory, blockpos1, _wood);

                                        branchHeight = j2;
                                    }
                                }

                                ++l4;
                            }

                            if (branchHeight > 0)
                            {
                                BlockWorldPos blockpos3 = new BlockWorldPos(woodX, branchHeight, woodZ);

                                for (int xOffset = -2; xOffset <= 2; ++xOffset)
                                {
                                    for (int zOffset = -2; zOffset <= 2; ++zOffset)
                                    {
                                        if (Math.Abs(xOffset) != 2 || Math.Abs(zOffset) != 2)
                                        {
                                            await world.SetBlockStateUnsafe(this.GrainFactory, BlockWorldPos.Add(blockpos3, xOffset, 0, zOffset), _leaves);
                                        }
                                    }
                                }

                                blockpos3 = blockpos3.Up();

                                for (int xOffset = -1; xOffset <= 1; ++xOffset)
                                {
                                    for (int zOffset = -1; zOffset <= 1; ++zOffset)
                                    {
                                        await world.SetBlockStateUnsafe(this.GrainFactory, BlockWorldPos.Add(blockpos3, xOffset, 0, zOffset), _leaves);
                                    }
                                }
                            }
                        }

                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }
            }
            else
            {
                return(false);
            }
        }
Ejemplo n.º 8
0
        private async Task <bool> GenerateImpl(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, Random random)
        {
            int  height             = random.Next(4) + 6;
            int  j                  = 1 + random.Next(2);
            int  k                  = height - j;
            int  l                  = 2 + random.Next(2);
            bool canSustainTreeFlag = true;

            if (pos.Y >= 1 && pos.Y + height + 1 <= 255)
            {
                for (int y = pos.Y; y <= pos.Y + 1 + height && canSustainTreeFlag; ++y)
                {
                    int xzWidth;

                    if (y - pos.Y < j)
                    {
                        xzWidth = 0;
                    }
                    else
                    {
                        xzWidth = l;
                    }

                    for (int x = pos.X - xzWidth; x <= pos.X + xzWidth && canSustainTreeFlag; ++x)
                    {
                        for (int z = pos.Z - xzWidth; z <= pos.Z + xzWidth && canSustainTreeFlag; ++z)
                        {
                            if (y >= 0 && y < 256)
                            {
                                BlockState state = await GetBlock(world, chunkWorldPos, new BlockWorldPos(x, y, z));

                                if (!(state.IsAir() ||
                                      state.IsLeaves()))
                                {
                                    canSustainTreeFlag = false;
                                }
                            }
                            else
                            {
                                canSustainTreeFlag = false;
                            }
                        }
                    }
                }

                if (!canSustainTreeFlag)
                {
                    return(false);
                }
                else
                {
                    BlockState state = await GetBlock(world, chunkWorldPos, new BlockWorldPos(pos.X, pos.Y - 1, pos.Z));

                    if (CanSustainTree(PlantsType.Spruce, state) && pos.Y < 256 - height - 1)
                    {
                        int xzWidth = random.Next(2);
                        int j3      = 1;
                        int k3      = 0;

                        for (int l3 = 0; l3 <= k; ++l3)
                        {
                            int y = pos.Y + height - l3;

                            for (int x = pos.X - xzWidth; x <= pos.X + xzWidth; ++x)
                            {
                                int deltaX = x - pos.X;

                                for (int z = pos.Z - xzWidth; z <= pos.Z + xzWidth; ++z)
                                {
                                    int deltaZ = z - pos.Z;

                                    if (Math.Abs(deltaX) != xzWidth || Math.Abs(deltaZ) != xzWidth || xzWidth <= 0)
                                    {
                                        state = await GetBlock(world, chunkWorldPos, new BlockWorldPos(x, y, z));

                                        if (state.IsAir() ||
                                            state.IsLeaves() ||
                                            state.IsSameId(BlockStates.Vines()))
                                        {
                                            await SetBlock(world, chunkWorldPos, new BlockWorldPos(x, y, z), _leaves);
                                        }
                                    }
                                }
                            }

                            if (xzWidth >= j3)
                            {
                                xzWidth = k3;
                                k3      = 1;
                                ++j3;

                                if (j3 > l)
                                {
                                    j3 = l;
                                }
                            }
                            else
                            {
                                ++xzWidth;
                            }
                        }

                        int heightLeft = random.Next(3);

                        for (int y = 0; y < height - heightLeft; ++y)
                        {
                            BlockWorldPos upN = new BlockWorldPos(pos.X, pos.Y + y, pos.Z);
                            state = await GetBlock(world, chunkWorldPos, upN);

                            if (state.IsAir() || state.IsSameId(BlockStates.Leaves()) || state.IsSameId(BlockStates.Leaves2()))
                            {
                                await SetBlock(world, chunkWorldPos, upN, _wood);
                            }
                        }

                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }
            }
            else
            {
                return(false);
            }
        }
Ejemplo n.º 9
0
        public override void Generate(IWorld world, IGrainFactory grainFactory, ChunkColumnCompactStorage chunk, Biome biome, Random random, BlockWorldPos pos)
        {
            int height = random.Next(3) + _minTreeHeight;

            // 不超出世界边界
            if (pos.Y >= 1 && pos.Y + height + 1 <= 256)
            {
                bool canTreeGrow = CanTreeGrow(world, grainFactory, chunk, biome, random, pos, height);
                if (canTreeGrow)
                {
                    BlockWorldPos downPos      = new BlockWorldPos(pos.X, pos.Y - 1, pos.Z);
                    BlockChunkPos chunkDownPos = downPos.ToBlockChunkPos();
                    BlockState    downBlock    = chunk[chunkDownPos.X, chunkDownPos.Y, chunkDownPos.Z];

                    // 是可生成树的土壤
                    bool isSoil = CanSustainTree(_treeType, downBlock);

                    if (isSoil && pos.Y < 256 - height - 1)
                    {
                        // 生成叶子
                        for (int y = pos.Y + height - 3; y <= pos.Y + height; ++y)
                        {
                            int restHeight = y - (pos.Y + height);
                            int xzSize     = 1 - restHeight / 2;

                            for (int x = pos.X - xzSize; x <= pos.X + xzSize; ++x)
                            {
                                int xOffset = x - pos.X;

                                for (int z = pos.Z - xzSize; z <= pos.Z + xzSize; ++z)
                                {
                                    int zOffset = z - pos.Z;

                                    if (Math.Abs(xOffset) != xzSize ||
                                        Math.Abs(zOffset) != xzSize || // 不在边缘4个点
                                        (random.Next(2) != 0 &&
                                         restHeight != 0))
                                    {
                                        BlockWorldPos blockpos      = new BlockWorldPos(x, y, z);
                                        BlockChunkPos chunkBlockPos = blockpos.ToBlockChunkPos();
                                        BlockState    block         = chunk[chunkBlockPos.X, chunkBlockPos.Y, chunkBlockPos.Z];

                                        if (block.IsAir() ||
                                            block.IsLeaves() ||
                                            block.IsId(BlockId.Vine))
                                        {
                                            chunk[chunkBlockPos.X, chunkBlockPos.Y, chunkBlockPos.Z] = _leaves;
                                        }
                                    }
                                }
                            }
                        }

                        // 生成木头
                        BlockWorldPos upPos = pos;
                        for (int y = 0; y < height; ++y)
                        {
                            BlockChunkPos chunkUpPos = upPos.ToBlockChunkPos();
                            BlockState    upBlock    = chunk[chunkUpPos.X, chunkUpPos.Y, chunkUpPos.Z];

                            if (upBlock.IsAir() ||
                                upBlock.IsLeaves() ||
                                upBlock.IsId(BlockId.Vine))
                            {
                                chunk[chunkUpPos.X, chunkUpPos.Y, chunkUpPos.Z] = _wood;
                            }

                            // 生成藤蔓
                            if (_vines && y > 0)
                            {
                                if (random.Next(3) > 0 && chunk[chunkUpPos.X - 1, chunkUpPos.Y, chunkUpPos.Z].IsAir())
                                {
                                    chunk[chunkUpPos.X - 1, chunkUpPos.Y, chunkUpPos.Z] = BlockStates.Vine(new VineType {
                                        East = VineEastType.True
                                    });
                                }

                                if (random.Next(3) > 0 && chunk[chunkUpPos.X + 1, chunkUpPos.Y, chunkUpPos.Z].IsAir())
                                {
                                    chunk[chunkUpPos.X + 1, chunkUpPos.Y, chunkUpPos.Z] = BlockStates.Vine(new VineType {
                                        West = VineWestType.True
                                    });
                                }

                                if (random.Next(3) > 0 && chunk[chunkUpPos.X, chunkUpPos.Y, chunkUpPos.Z - 1].IsAir())
                                {
                                    chunk[chunkUpPos.X, chunkUpPos.Y, chunkUpPos.Z - 1] = BlockStates.Vine(new VineType {
                                        South = VineSouthType.True
                                    });
                                }

                                if (random.Next(3) > 0 && chunk[chunkUpPos.X, chunkUpPos.Y, chunkUpPos.Z + 1].IsAir())
                                {
                                    chunk[chunkUpPos.X, chunkUpPos.Y, chunkUpPos.Z + 1] = BlockStates.Vine(new VineType {
                                        North = VineNorthType.True
                                    });
                                }
                            }

                            ++upPos.Y;
                        }

                        // 生成藤蔓
                        BlockChunkPos chunkPos = pos.ToBlockChunkPos();
                        if (_vines)
                        {
                            for (int y = chunkPos.Y + height - 3; y <= chunkPos.Y + height; ++y)
                            {
                                int restHeight = y - (chunkPos.Y + height);
                                int xzSize     = 2 - restHeight / 2;

                                for (int x = chunkPos.X - xzSize; x <= chunkPos.X + xzSize; ++x)
                                {
                                    for (int z = chunkPos.Z - xzSize; z <= chunkPos.Z + xzSize; ++z)
                                    {
                                        if (chunk[x, y, z].IsLeaves())
                                        {
                                            if (random.Next(4) == 0 && chunk[x - 1, y, z].IsAir())
                                            {
                                                chunk[x - 1, y, z] = BlockStates.Vine(new VineType {
                                                    East = VineEastType.True
                                                });
                                            }

                                            if (random.Next(4) == 0 && chunk[x + 1, y, z].IsAir())
                                            {
                                                chunk[x + 1, y, z] = BlockStates.Vine(new VineType {
                                                    West = VineWestType.True
                                                });
                                            }

                                            if (random.Next(4) == 0 && chunk[x, y, z - 1].IsAir())
                                            {
                                                chunk[x, y, z - 1] = BlockStates.Vine(new VineType {
                                                    South = VineSouthType.True
                                                });
                                            }

                                            if (random.Next(4) == 0 && chunk[x, y, z + 1].IsAir())
                                            {
                                                chunk[x, y, z + 1] = BlockStates.Vine(new VineType {
                                                    North = VineNorthType.True
                                                });
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 10
0
        protected async Task GenerateImpl(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, Random random)
        {
            int height = random.Next(3) + _minTreeHeight;

            // 不超出世界边界
            if (pos.Y >= 1 && pos.Y + height + 1 <= 256)
            {
                bool canTreeGrow = await CanTreeGrow(world, chunkWorldPos, pos, height);

                if (canTreeGrow)
                {
                    BlockWorldPos downPos   = new BlockWorldPos(pos.X, pos.Y - 1, pos.Z);
                    BlockState    downBlock = await GetBlock(world, chunkWorldPos, downPos);

                    // 是可生成树的土壤
                    bool isSoil = CanSustainTree(_treeType, downBlock);

                    if (isSoil && pos.Y < 256 - height - 1)
                    {
                        // 生成叶子
                        for (int y = pos.Y + height - 3; y <= pos.Y + height; ++y)
                        {
                            int restHeight = y - (pos.Y + height);
                            int xzSize     = 1 - restHeight / 2;

                            for (int x = pos.X - xzSize; x <= pos.X + xzSize; ++x)
                            {
                                int xOffset = x - pos.X;

                                for (int z = pos.Z - xzSize; z <= pos.Z + xzSize; ++z)
                                {
                                    int zOffset = z - pos.Z;

                                    if (Math.Abs(xOffset) != xzSize ||
                                        Math.Abs(zOffset) != xzSize || // 不在边缘4个点
                                        (random.Next(2) != 0 &&
                                         restHeight != 0))
                                    {
                                        BlockWorldPos blockpos = new BlockWorldPos(x, y, z);
                                        BlockState    block    = await GetBlock(world, chunkWorldPos, blockpos);

                                        if (block.IsAir() ||
                                            block.IsLeaves() ||
                                            block.IsId(BlockId.Vine))
                                        {
                                            await SetBlock(world, chunkWorldPos, blockpos, _leaves);
                                        }
                                    }
                                }
                            }
                        }

                        // 生成木头
                        BlockWorldPos upPos = pos;
                        for (int y = 0; y < height; ++y)
                        {
                            BlockState upBlock = await GetBlock(world, chunkWorldPos, upPos);

                            if (upBlock.IsAir() ||
                                upBlock.IsLeaves() ||
                                upBlock.IsId(BlockId.Vine))
                            {
                                await SetBlock(world, chunkWorldPos, upPos, _wood);
                            }

                            // 生成藤蔓
                            if (_vines && y > 0)
                            {
                                await RandomSetIfAir(world, chunkWorldPos, upPos.X - 1, upPos.Y, upPos.Z, BlockStates.Vine(new VineType {
                                    East = VineEastType.True
                                }), random, 0.666f);

                                await RandomSetIfAir(world, chunkWorldPos, upPos.X + 1, upPos.Y, upPos.Z, BlockStates.Vine(new VineType {
                                    West = VineWestType.True
                                }), random, 0.666f);

                                await RandomSetIfAir(world, chunkWorldPos, upPos.X, upPos.Y, upPos.Z - 1, BlockStates.Vine(new VineType {
                                    South = VineSouthType.True
                                }), random, 0.666f);

                                await RandomSetIfAir(world, chunkWorldPos, upPos.X, upPos.Y, upPos.Z + 1, BlockStates.Vine(new VineType {
                                    North = VineNorthType.True
                                }), random, 0.666f);
                            }

                            ++upPos.Y;
                        }

                        // 生成藤蔓
                        if (_vines)
                        {
                            for (int y = pos.Y + height - 3; y <= pos.Y + height; ++y)
                            {
                                int restHeight = y - (pos.Y + height);
                                int xzSize     = 2 - restHeight / 2;

                                for (int x = pos.X - xzSize; x <= pos.X + xzSize; ++x)
                                {
                                    for (int z = pos.Z - xzSize; z <= pos.Z + xzSize; ++z)
                                    {
                                        if ((await GetBlock(world, chunkWorldPos, new BlockWorldPos(x, y, z))).IsLeaves())
                                        {
                                            await RandomSetIfAir(world, chunkWorldPos, x - 1, y, z, BlockStates.Vine(new VineType {
                                                East = VineEastType.True
                                            }), random, 0.25f);

                                            await RandomSetIfAir(world, chunkWorldPos, x + 1, y, z, BlockStates.Vine(new VineType {
                                                West = VineWestType.True
                                            }), random, 0.25f);

                                            await RandomSetIfAir(world, chunkWorldPos, x, y, z - 1, BlockStates.Vine(new VineType {
                                                South = VineSouthType.True
                                            }), random, 0.25f);

                                            await RandomSetIfAir(world, chunkWorldPos, x, y, z + 1, BlockStates.Vine(new VineType {
                                                North = VineNorthType.True
                                            }), random, 0.25f);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 11
0
        private async Task <bool> GenerateImpl(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, Random rand)
        {
            int  height = rand.Next(3) + rand.Next(3) + 5;
            bool flag   = true;

            if (pos.Y >= 1 && pos.Y + height + 1 <= 256)
            {
                for (int y = pos.Y; y <= pos.Y + 1 + height; ++y)
                {
                    int xzRange = 1;

                    if (y == pos.Y)
                    {
                        xzRange = 0;
                    }

                    if (y >= pos.Y + 1 + height - 2)
                    {
                        xzRange = 2;
                    }

                    for (int xOffset = pos.X - xzRange; xOffset <= pos.X + xzRange && flag; ++xOffset)
                    {
                        for (int zOffset = pos.Z - xzRange; zOffset <= pos.Z + xzRange && flag; ++zOffset)
                        {
                            if (y >= 0 && y < 256)
                            {
                                var blockState = await world.GetBlockStateUnsafe(this.GrainFactory, new BlockWorldPos(xOffset, y, zOffset));

                                if (!IsReplaceable(blockState))
                                {
                                    flag = false;
                                }
                            }
                            else
                            {
                                flag = false;
                            }
                        }
                    }
                }

                if (!flag)
                {
                    return(false);
                }
                else
                {
                    BlockWorldPos down  = pos.Down();
                    BlockState    state = await world.GetBlockStateUnsafe(this.GrainFactory, down);

                    bool isSoil = IsSoil(state);

                    if (isSoil && pos.Y < ChunkConstants.ChunkHeight - height - 1)
                    {
                        // state.getBlock().onPlantGrow(state, world, down, pos);
                        Facing enumfacing = Facing.RadomFacing(rand, Plane.XZ);
                        int    k2         = height - rand.Next(4) - 1;
                        int    l2         = 3 - rand.Next(3);
                        int    i3         = pos.X;
                        int    j1         = pos.Z;
                        int    k1         = 0;

                        for (int l1 = 0; l1 < height; ++l1)
                        {
                            int i2 = pos.Y + l1;

                            if (l1 >= k2 && l2 > 0)
                            {
                                i3 += enumfacing.ToBlockVector().X;
                                j1 += enumfacing.ToBlockVector().Z;
                                --l2;
                            }

                            BlockWorldPos blockpos = new BlockWorldPos(i3, i2, j1);
                            state = await world.GetBlockStateUnsafe(this.GrainFactory, blockpos);

                            if (state.IsAir() || state.IsLeaves())
                            {
                                await world.SetBlockStateUnsafe(this.GrainFactory, blockpos, _wood);

                                k1 = i2;
                            }
                        }

                        BlockWorldPos blockpos2 = new BlockWorldPos(i3, k1, j1);

                        for (int j3 = -3; j3 <= 3; ++j3)
                        {
                            for (int i4 = -3; i4 <= 3; ++i4)
                            {
                                if (Math.Abs(j3) != 3 || Math.Abs(i4) != 3)
                                {
                                    await world.SetBlockStateUnsafe(this.GrainFactory, BlockWorldPos.Add(blockpos2, j3, 0, i4), _leaves);
                                }
                            }
                        }

                        blockpos2 = blockpos2.Up();

                        for (int k3 = -1; k3 <= 1; ++k3)
                        {
                            for (int j4 = -1; j4 <= 1; ++j4)
                            {
                                await world.SetBlockStateUnsafe(this.GrainFactory, BlockWorldPos.Add(blockpos2, k3, 0, j4), _leaves);
                            }
                        }

                        await world.SetBlockStateUnsafe(this.GrainFactory, blockpos2.East(2), _leaves);

                        await world.SetBlockStateUnsafe(this.GrainFactory, blockpos2.West(2), _leaves);

                        await world.SetBlockStateUnsafe(this.GrainFactory, blockpos2.South(2), _leaves);

                        await world.SetBlockStateUnsafe(this.GrainFactory, blockpos2.North(2), _leaves);

                        i3 = pos.X;
                        j1 = pos.Z;
                        Facing enumfacing1 = Facing.RadomFacing(rand, Plane.XZ);

                        if (enumfacing1 != enumfacing)
                        {
                            int l3 = k2 - rand.Next(2) - 1;
                            int k4 = 1 + rand.Next(3);
                            k1 = 0;

                            for (int l4 = l3; l4 < height && k4 > 0; --k4)
                            {
                                if (l4 >= 1)
                                {
                                    int j2 = pos.Y + l4;
                                    i3 += enumfacing1.ToBlockVector().X;
                                    j1 += enumfacing1.ToBlockVector().Z;
                                    BlockWorldPos blockpos1 = new BlockWorldPos(i3, j2, j1);
                                    state = await world.GetBlockStateUnsafe(this.GrainFactory, blockpos1);

                                    if (state.IsAir() || state.IsLeaves())
                                    {
                                        await world.SetBlockStateUnsafe(this.GrainFactory, blockpos1, _wood);

                                        k1 = j2;
                                    }
                                }

                                ++l4;
                            }

                            if (k1 > 0)
                            {
                                BlockWorldPos blockpos3 = new BlockWorldPos(i3, k1, j1);

                                for (int i5 = -2; i5 <= 2; ++i5)
                                {
                                    for (int k5 = -2; k5 <= 2; ++k5)
                                    {
                                        if (Math.Abs(i5) != 2 || Math.Abs(k5) != 2)
                                        {
                                            await world.SetBlockStateUnsafe(this.GrainFactory, BlockWorldPos.Add(blockpos3, i5, 0, k5), _leaves);
                                        }
                                    }
                                }

                                blockpos3 = blockpos3.Up();

                                for (int j5 = -1; j5 <= 1; ++j5)
                                {
                                    for (int l5 = -1; l5 <= 1; ++l5)
                                    {
                                        await world.SetBlockStateUnsafe(this.GrainFactory, BlockWorldPos.Add(blockpos3, j5, 0, l5), _leaves);
                                    }
                                }
                            }
                        }

                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }
            }
            else
            {
                return(false);
            }
        }
Ejemplo n.º 12
0
        private async Task <bool> GenerateImpl(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, Random random)
        {
            int height       = random.Next(5) + 7;
            int heightLeaves = height - random.Next(2) - 3;
            int k            = height - heightLeaves;
            int l            = 1 + random.Next(k + 1);

            if (pos.Y >= 1 && pos.Y + height + 1 <= 256)
            {
                bool canSustainTreeFlag = true;

                for (int y = pos.Y; y <= pos.Y + 1 + height && canSustainTreeFlag; ++y)
                {
                    int xzWidth = 1;

                    if (y - pos.Y < heightLeaves)
                    {
                        xzWidth = 0;
                    }
                    else
                    {
                        xzWidth = l;
                    }

                    for (int x = pos.X - xzWidth; x <= pos.X + xzWidth && canSustainTreeFlag; ++x)
                    {
                        for (int z = pos.Z - xzWidth; z <= pos.Z + xzWidth && canSustainTreeFlag; ++z)
                        {
                            if (y >= 0 && y < 256)
                            {
                                BlockState block = await GetBlock(world, chunkWorldPos, new BlockWorldPos(x, y, z));

                                if (!(block.IsAir() ||
                                      block.IsLeaves() ||
                                      block.IsId(BlockId.Vine)))
                                {
                                    canSustainTreeFlag = false;
                                }
                            }
                            else
                            {
                                canSustainTreeFlag = false;
                            }
                        }
                    }
                }

                if (!canSustainTreeFlag)
                {
                    return(false);
                }
                else
                {
                    BlockState state = await GetBlock(world, chunkWorldPos, new BlockWorldPos(pos.X, pos.Y - 1, pos.Z));

                    bool isSoil = CanSustainTree(PlantsType.Spruce, state);

                    if (isSoil && pos.Y < 256 - height - 1)
                    {
                        int xzWidth = 0;

                        for (int y = pos.Y + height; y >= pos.Y + heightLeaves; --y)
                        {
                            for (int x = pos.X - xzWidth; x <= pos.X + xzWidth; ++x)
                            {
                                int deltaX = x - pos.X;

                                for (int z = pos.Z - xzWidth; z <= pos.Z + xzWidth; ++z)
                                {
                                    int deltaZ = z - pos.Z;

                                    if (Math.Abs(deltaX) != xzWidth || Math.Abs(deltaZ) != xzWidth || xzWidth <= 0)
                                    {
                                        state = await GetBlock(world, chunkWorldPos, new BlockWorldPos(x, y, z));

                                        if (state.IsAir() ||
                                            state.IsLeaves() ||
                                            state.IsId(BlockId.Vine))
                                        {
                                            await SetBlock(world, chunkWorldPos, new BlockWorldPos(x, y, z), _leaves);
                                        }
                                    }
                                }
                            }

                            if (xzWidth >= 1 && y == pos.Y + heightLeaves + 1)
                            {
                                --xzWidth;
                            }
                            else if (xzWidth < l)
                            {
                                ++xzWidth;
                            }
                        }

                        for (int y = 0; y < height - 1; ++y)
                        {
                            BlockWorldPos upN = new BlockWorldPos(pos.X, pos.Y + y, pos.Z);
                            state = await GetBlock(world, chunkWorldPos, upN);

                            if (state.IsAir() || state.IsLeaves())
                            {
                                await SetBlock(world, chunkWorldPos, upN, _wood);
                            }
                        }

                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }
            }
            else
            {
                return(false);
            }
        }