public static bool IsMobCollided(this BlockState state)
 {
     return(!state.IsSameId(BlockStates.Air()) &&
            !state.IsSameId(BlockStates.Grass()) &&
            !state.IsSameId(BlockStates.LargeFlowers()) &&
            !state.IsSameId(BlockStates.Poppy()) &&
            !state.IsSameId(BlockStates.Dandelion()));
 }
Example #2
0
        public void IsSameIdTest()
        {
            BlockState state1 = BlockStates.Dirt();
            BlockState state2 = BlockStates.Dirt();
            BlockState state3 = BlockStates.Wood(WoodType.Birch);
            BlockState state4 = BlockStates.Wood(WoodType.Oak);

            Assert.True(state1 == state2);
            Assert.False(state1 == state3);
            Assert.False(state3.IsSameId(state2));
            Assert.True(state3.IsSameId(state4));
        }
Example #3
0
        public void IsSameIdTest()
        {
            BlockState state1 = BlockStates.Dirt();
            BlockState state2 = BlockStates.Dirt();
            BlockState state3 = BlockStates.BirchLog();
            BlockState state4 = BlockStates.OakLog();

            Assert.True(state1 == state2);
            Assert.False(state1 == state3);
            Assert.False(state3.IsSameId(state2));
            Assert.False(state3.IsSameId(state4));
        }
Example #4
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.IsSameId(BlockStates.Leaves()) &&
                                !state.IsSameId(BlockStates.Leaves2()))
                            {
                                result = false;
                            }
                        }
                        else
                        {
                            result = false;
                        }
                    }
                }
            }

            return(result);
        }
Example #5
0
        public async Task <bool> FinishedDigging(IEntity entity, IGrainFactory grainFactory, IWorld world, BlockWorldPos position, BlockState blockState, long usedTick, GameMode gameMode)
        {
            if (!blockState.IsSameId(BlockStates.Bedrock()))
            {
                var newState = BlockStates.Air();
                await world.SetBlockState(grainFactory, position, newState);

                // 产生 Pickup
                if (gameMode.ModeClass != GameMode.Class.Creative)
                {
                    var chunk        = position.ToChunkWorldPos();
                    var finder       = grainFactory.GetGrain <ICollectableFinder>(world.MakeAddressByPartitionKey(chunk));
                    var blockHandler = BlockHandler.Create((BlockId)blockState.Id);
                    var droppedSlot  = blockHandler.DropBlock(ItemId, blockState);
                    if (!droppedSlot.IsEmpty)
                    {
                        await finder.SpawnPickup(position + new Vector3(0.5f, 0.5f, 0.5f), new[] { droppedSlot }.AsImmutable());
                    }
                }

                return(true);
            }

            return(false);
        }
Example #6
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.IsSameId(BlockStates.Leaves()) &&
                                state.IsSameId(BlockStates.Leaves2()))
                            {
                                result = false;
                            }
                        }
                        else
                        {
                            result = false;
                        }
                    }
                }
            }

            return(result);
        }
 public static bool CanMobStand(this BlockState state)
 {
     return(!state.IsSameId(BlockStates.Air()) &&
            !state.IsSameId(BlockStates.Grass()) &&
            !state.IsSameId(BlockStates.Water()) &&
            !state.IsSameId(BlockStates.LargeFlowers()) &&
            !state.IsSameId(BlockStates.Poppy()) &&
            !state.IsSameId(BlockStates.Dandelion()));
 }
 // 一些特性
 public static int IsLightOpacity(this BlockState state)
 {
     if (state.IsSameId(BlockStates.Air()))
     {
         return(255);
     }
     else if (state.IsSameId(BlockStates.Water()))
     {
         return(255);
     }
     else if (state.IsSameId(BlockStates.Lava()))
     {
         return(255);
     }
     else if (state.IsSameId(BlockStates.Glass()))
     {
         return(255);
     }
     else if (state.IsSameId(BlockStates.Grass()))
     {
         return(255);
     }
     else if (state.IsSameId(BlockStates.Poppy()))
     {
         return(255);
     }
     else if (state.IsSameId(BlockStates.Dandelion()))
     {
         return(255);
     }
     else if (state.IsSameId(BlockStates.LargeFlowers()))
     {
         return(255);
     }
     else
     {
         return(0);
     }
 }
        public static async Task <bool> CanBlockStay(this BlockState state, IWorld world, IGrainFactory grainFactory, int x, int y, int z)
        {
            if (state.IsSameId(BlockStates.Grass()))
            {
                if (y > 0)
                {
                    var downState = await world.GetBlockState(grainFactory, x, y - 1, z);

                    if (downState == BlockStates.Dirt() ||
                        downState == BlockStates.Grass())
                    {
                        return(true);
                    }
                }

                return(false);
            }
            else
            {
                return(true);
            }
        }
Example #10
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;
            }
        }
Example #11
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;
            }
        }
Example #12
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.IsSameId(BlockStates.Leaves()) ||
                                            block.IsSameId(BlockStates.Vines()))
                                        {
                                            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.IsSameId(BlockStates.Leaves()) ||
                                upBlock.IsSameId(BlockStates.Vines()))
                            {
                                await SetBlock(world, chunkWorldPos, upPos, _wood);
                            }

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

                                await RandomSetIfAir(world, chunkWorldPos, upPos.X + 1, upPos.Y, upPos.Z, BlockStates.Vines(VineType.West), random, 0.666f);

                                await RandomSetIfAir(world, chunkWorldPos, upPos.X, upPos.Y, upPos.Z - 1, BlockStates.Vines(VineType.South), random, 0.666f);

                                await RandomSetIfAir(world, chunkWorldPos, upPos.X, upPos.Y, upPos.Z + 1, BlockStates.Vines(VineType.North), 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.Vines(VineType.East), random, 0.25f);

                                            await RandomSetIfAir(world, chunkWorldPos, x + 1, y, z, BlockStates.Vines(VineType.West), random, 0.25f);

                                            await RandomSetIfAir(world, chunkWorldPos, x, y, z - 1, BlockStates.Vines(VineType.South), random, 0.25f);

                                            await RandomSetIfAir(world, chunkWorldPos, x, y, z + 1, BlockStates.Vines(VineType.North), random, 0.25f);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Example #13
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.IsSameId(BlockStates.Leaves()) ||
                                            block.IsSameId(BlockStates.Vines()))
                                        {
                                            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.IsSameId(BlockStates.Leaves()) ||
                                upBlock.IsSameId(BlockStates.Vines()))
                            {
                                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.Vines(VineType.East);
                                }

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

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

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

                            ++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.Vines(VineType.East);
                                            }

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

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

                                            if (random.Next(4) == 0 && chunk[x, y, z + 1].IsAir())
                                            {
                                                chunk[x, y, z + 1] = BlockStates.Vines(VineType.North);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        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);
            }
        }
Example #15
0
 public static bool IsLeaves(this BlockState state)
 {
     return(state.IsSameId(BlockStates.Leaves()) || state.IsSameId(BlockStates.Leaves2()));
 }
        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.IsSameId(BlockStates.Vines())))
                                {
                                    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.IsSameId(BlockStates.Vines()))
                                        {
                                            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);
            }
        }