Example #1
0
 protected virtual void TrySetBlock(ChunkColumnStorage chunk, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, BlockState state)
 {
     if (pos.ToChunkWorldPos() == chunkWorldPos)
     {
         BlockChunkPos blockChunkPos = pos.ToBlockChunkPos();
         chunk[blockChunkPos.X, blockChunkPos.Y, blockChunkPos.Z] = state;
     }
 }
Example #2
0
        protected virtual Task <BlockState> GetBlock(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos)
        {
            var           chunkColumnKey = world.MakeAddressByPartitionKey(pos.ToChunkWorldPos());
            var           chunkGrain     = GrainFactory.GetGrain <IChunkColumn>(chunkColumnKey);
            BlockChunkPos blockChunkPos  = pos.ToBlockChunkPos();

            return(chunkGrain.GetBlockStateUnsafe(blockChunkPos.X, blockChunkPos.Y, blockChunkPos.Z));
        }
        public Task <BiomeId> GetBlockBiome(BlockWorldPos pos)
        {
            BlockChunkPos blockChunkPos  = pos.ToBlockChunkPos();
            ChunkWorldPos chunkWorldPos  = pos.ToChunkWorldPos();
            IWorld        world          = AttachedObject.GetWorld();
            var           chunkColumnKey = world.MakeAddressByPartitionKey(new ChunkWorldPos(chunkWorldPos.X, chunkWorldPos.Z));

            return(GrainFactory.GetGrain <IChunkColumn>(chunkColumnKey).GetBlockBiome(
                       blockChunkPos.X,
                       blockChunkPos.Z));
        }
Example #4
0
 public bool CanFlowerGrow(PlantsType type, ChunkColumnStorage chunk, BlockChunkPos pos)
 {
     if (chunk[pos.X, pos.Y - 1, pos.Z] == BlockStates.GrassBlock() ||
         chunk[pos.X, pos.Y - 1, pos.Z] == BlockStates.Dirt())
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
Example #5
0
        public override void Generate(IWorld world, IGrainFactory grainFactory, ChunkColumnCompactStorage chunk, Biome biome, Random random, BlockWorldPos pos)
        {
            BlockChunkPos chunkPos = pos.ToBlockChunkPos();
            int           x        = chunkPos.X;
            int           y        = chunkPos.Y;
            int           z        = chunkPos.Z;

            // TODO use block accessor
            if (chunk[x, y, z].IsAir() &&
                chunk[x, y - 1, z] == BlockStates.GrassBlock())
            {
                chunk[x, y, z] = BlockStates.Grass(GrassType.TallGrass);
            }
        }
Example #6
0
        public bool CanMobStand(IWorld world, IGrainFactory grainFactory, IChunkColumnStorage chunk, Random random, BlockChunkPos pos)
        {
            // TODO 以后结合boundbox判断
            BlockChunkPos downPos = new BlockChunkPos(pos.X, pos.Y - 1, pos.Z);

            if (chunk[pos.X, pos.Y - 1, pos.Z].IsLightOpacity() == 0)
            {
                if (chunk[pos.X, pos.Y, pos.Z] == BlockStates.Air() &&
                    chunk[pos.X, pos.Y + 1, pos.Z] == BlockStates.Air())
                {
                    return(true);
                }
            }

            return(false);
        }
Example #7
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);
        }
Example #8
0
        public override void Generate(IWorld world, IGrainFactory grainFactory, ChunkColumnStorage chunk, Biome biome, Random random, BlockWorldPos pos)
        {
            int num = random.Next(_flowersMaxNum);

            for (int i = 0; i < num; ++i)
            {
                BlockWorldPos blockpos = BlockWorldPos.Add(pos, random.Next(8), random.Next(4), random.Next(8));
                BlockChunkPos chunkpos = blockpos.ToBlockChunkPos();
                if (chunk[chunkpos.X, chunkpos.Y, chunkpos.Z].IsAir() &&
                    blockpos.Y < 254 &&
                    CanFlowerGrow(_flowerType, chunk, chunkpos))
                {
                    chunk[chunkpos.X, chunkpos.Y, chunkpos.Z]     = BlockStates.LargeFlowers(LargeFlowerType.Sunflower);
                    chunk[chunkpos.X, chunkpos.Y + 1, chunkpos.Z] = BlockStates.LargeFlowers(LargeFlowerType.TopHalfFlag);
                }
            }
        }
        public override void Generate(IWorld world, IGrainFactory grainFactory, ChunkColumnCompactStorage chunk, Biome biome, Random random, BlockWorldPos pos)
        {
            int num = random.Next(_grassMaxNum);

            for (int i = 0; i < num; ++i)
            {
                BlockWorldPos blockpos = BlockWorldPos.Add(pos, random.Next(8), random.Next(4), random.Next(8));
                BlockChunkPos chunkpos = blockpos.ToBlockChunkPos();
                if (chunk[chunkpos.X, chunkpos.Y, chunkpos.Z].IsAir() &&
                    blockpos.Y < 254 &&
                    CanGrassGrow(_grassType, chunk, chunkpos))
                {
                    chunk[chunkpos.X, chunkpos.Y, chunkpos.Z]     = BlockStates.TallGrass(TallGrassHalfType.Lower);
                    chunk[chunkpos.X, chunkpos.Y + 1, chunkpos.Z] = BlockStates.TallGrass(TallGrassHalfType.Upper);
                }
            }
        }
Example #10
0
        public override void Generate(IWorld world, IGrainFactory grainFactory, ChunkColumnStorage chunk, Biome biome, Random random, BlockWorldPos pos)
        {
            int           height   = random.Next(3) + _minCactiHeight;
            BlockChunkPos chunkPos = pos.ToBlockChunkPos();

            // 不超出世界边界
            if (pos.Y >= 1 && pos.Y + height + 1 <= 256)
            {
                if (CanCactiGrow(world, grainFactory, chunk, biome, random, pos, height))
                {
                    BlockState state = chunk[chunkPos.X, chunkPos.Y - 1, chunkPos.Z];
                    if (CanSustainCacti(state))
                    {
                        for (int y = 0; y < height; ++y)
                        {
                            chunk[chunkPos.X, chunkPos.Y + y, chunkPos.Z] = BlockStates.Cactus(CactusType.Interval15);
                        }
                    }
                }
            }
        }
Example #11
0
        public override void Generate(IWorld world, IGrainFactory grainFactory, ChunkColumnCompactStorage chunk, Biome biome, Random random, BlockWorldPos pos)
        {
            BlockChunkPos chunkPos = pos.ToBlockChunkPos();
            int           x        = chunkPos.X;
            int           y        = chunkPos.Y;
            int           z        = chunkPos.Z;

            // TODO use block accessor
            if (chunk[x, y, z].IsAir() &&
                chunk[x, y - 1, z] == BlockStates.GrassBlock())
            {
                var flowerType = biome.GetRandomFlower(random);
                switch (flowerType)
                {
                case PlantsType.Poppy:
                    chunk[x, y, z] = BlockStates.Poppy();
                    break;

                case PlantsType.Dandelion:
                    chunk[x, y, z] = BlockStates.Dandelion();
                    break;
                }
            }
        }
Example #12
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);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Example #13
0
        public void Generate(IWorld world, IGrainFactory grainFactory, ChunkColumnCompactStorage chunk, Random rand, BlockWorldPos position)
        {
            // 在xz平面上的方向
            float angle = (float)rand.NextDouble() * (float)Math.PI;

            // 起始点和结束点
            double startX = (double)((float)(position.X + 8) + Math.Sin(angle) * (float)NumberOfBlocks / 8.0F);
            double endX   = (double)((float)(position.X + 8) - Math.Sin(angle) * (float)NumberOfBlocks / 8.0F);
            double startZ = (double)((float)(position.Z + 8) + Math.Cos(angle) * (float)NumberOfBlocks / 8.0F);
            double endZ   = (double)((float)(position.Z + 8) - Math.Cos(angle) * (float)NumberOfBlocks / 8.0F);
            double startY = (double)(position.Y + rand.Next(3) - 2);
            double endY   = (double)(position.Y + rand.Next(3) - 2);

            for (int i = 0; i < NumberOfBlocks; ++i)
            {
                // 插值参数
                float t = (float)i / (float)NumberOfBlocks;

                // 椭球中心
                double centerX = startX + (endX - startX) * (double)t;
                double centerY = startY + (endY - startY) * (double)t;
                double centerZ = startZ + (endZ - startZ) * (double)t;

                // 椭球尺寸(可以看出XZ和Y尺寸一样,应该是球)
                double scale      = rand.NextDouble() * (double)NumberOfBlocks / 16.0D;
                double diameterXZ = (double)(Math.Sin((float)Math.PI * t) + 1.0F) * scale + 1.0D;
                double diameterY  = (double)(Math.Sin((float)Math.PI * t) + 1.0F) * scale + 1.0D;

                // 椭球包围盒
                int minX = (int)Math.Floor(centerX - diameterXZ / 2.0D);
                int minY = (int)Math.Floor(centerY - diameterY / 2.0D);
                int minZ = (int)Math.Floor(centerZ - diameterXZ / 2.0D);
                int maxX = (int)Math.Floor(centerX + diameterXZ / 2.0D);
                int maxY = (int)Math.Floor(centerY + diameterY / 2.0D);
                int maxZ = (int)Math.Floor(centerZ + diameterXZ / 2.0D);

                // 把这个椭球里的方块替换为矿石
                for (int x = minX; x <= maxX; ++x)
                {
                    double xDist = ((double)x + 0.5D - centerX) / (diameterXZ / 2.0D);

                    // 参考椭球方程
                    if (xDist * xDist < 1.0D)
                    {
                        for (int y = minY; y <= maxY; ++y)
                        {
                            double yDist = ((double)y + 0.5D - centerY) / (diameterY / 2.0D);

                            // 参考椭球方程
                            if (xDist * xDist + yDist * yDist < 1.0D)
                            {
                                for (int z = minZ; z <= maxZ; ++z)
                                {
                                    double zDist = ((double)z + 0.5D - centerZ) / (diameterXZ / 2.0D);

                                    // 参考椭球方程
                                    if (xDist * xDist + yDist * yDist + zDist * zDist < 1.0D)
                                    {
                                        BlockWorldPos blockpos   = new BlockWorldPos(x, y, z);
                                        BlockChunkPos posInChunk = blockpos.ToBlockChunkPos();
                                        if (posInChunk.Y >= 0 &&
                                            posInChunk.Y < 255 &&
                                            chunk[posInChunk.X, posInChunk.Y, posInChunk.Z] == BlockStates.Stone())
                                        {
                                            // 替换为矿石
                                            chunk[posInChunk.X, posInChunk.Y, posInChunk.Z] = OreBlock;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }