Example #1
0
        /*
         * public int GetMetadata(BlockPos pos)
         * {
         *  Chunk chunk = GetChunk(ChunkPos.FromWorldSpace(pos));
         *  if (chunk == null || !chunk.HasData)
         *      return -1;
         *
         *  return chunk.GetMetadata(ChunkPos.ToChunkLocal(pos));
         * }*/

        /*
         * public void SetMetadata(BlockPos pos, int meta)
         * {
         *  Chunk chunk = GetChunk(ChunkPos.FromWorldSpace(pos));
         *  if (chunk == null || !chunk.HasData)
         *      return;
         *
         *  chunk.SetMetadata(ChunkPos.ToChunkLocal(pos), meta);
         * }*/

        public int GetHeightAtPos(float x, float z)
        {
            BlockPos pos = new BlockPos(x, 0, z);

            Chunk chunk = GetChunk(pos.ChunkPos());

            if (chunk == null || !chunk.HasData)
            {
                return(0);
            }

            return(chunk.GetHeightAtPos(MathUtil.ToLocal(pos.X, Chunk.ChunkSize), MathUtil.ToLocal(pos.Z, Chunk.ChunkSize)));
        }
        public static Chunk loadChunk(BlockPos pos)
        {
            var chunkPos = pos.ChunkPos();

            var regionPos = new BlockPos(chunkPos.x / (4 * 16), 0, chunkPos.z / (4 * 16));
            var fileName  = $"r.{regionPos.x}.{regionPos.z}.region";

            var bf = new BinaryFormatter();

            try
            {
                locker.AcquireReaderLock(1000);

                if (!Directory.Exists(dir) || !File.Exists($"{dir}/{fileName}"))
                {
                    return(null);
                }

                //read, if exists
                using (var fs = File.Open($"{dir}/{fileName}", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    fs.SetLength(_regionInfoSize);

                    var regionInfo   = (RegionInfo)bf.Deserialize(fs);
                    var chunkFilePos = regionInfo.getChunkPos(chunkPos);

                    fs.Position = chunkFilePos;
                    fs.SetLength(_chunkSize);

                    var cc = (ChunkCache)bf.Deserialize(fs);

                    return(Chunk.CreateFromCache(cc));
                }
            }
            catch
            {
                return(null);
            }
            finally
            {
                locker.ReleaseLock();
            }
        }
Example #3
0
 public override void RemoveTileEntity(BlockPos pos)
 {
     GetChunk(pos.ChunkPos())?.RemoveTileEntity(ChunkPos.ToChunkLocal(pos));
 }
Example #4
0
        //TODO move this to some chunk generator
        public short[,,] GenerateChunk(ChunkPos chunkPos, bool updateContainingEntities)
        {
            Chunk chunk = null;

            lock (Chunks)
            {
                chunk = PutChunk(chunkPos, null);
            }

            if (chunk == null)
            {
                return(null);
            }

            var air = BlockRegistry.GetBlock <BlockAir>().GetState();

            var leavesGreen  = BlockRegistry.GetBlock <BlockLeaves>().GetState();
            var leavesYellow = BlockRegistry.GetBlock <BlockLeaves>().GetState(1);
            var leavesOrange = BlockRegistry.GetBlock <BlockLeaves>().GetState(2);
            var leavesRed    = BlockRegistry.GetBlock <BlockLeaves>().GetState(3);

            var log         = BlockRegistry.GetBlock <BlockLog>().GetState();
            var grass       = BlockRegistry.GetBlock <BlockGrass>().GetState();
            var dirt        = BlockRegistry.GetBlock <BlockDirt>().GetState();
            var stone       = BlockRegistry.GetBlock <BlockStone>().GetState();
            var rare        = BlockRegistry.GetBlock <BlockRare>().GetState();
            var bedrock     = BlockRegistry.GetBlock <BlockBedrock>().GetState();
            var tallgrass   = BlockRegistry.GetBlock <BlockTallGrass>().GetState();
            var tulipRed    = BlockRegistry.GetBlock <BlockTulipRed>().GetState();
            var tulipOrange = BlockRegistry.GetBlock <BlockTulipOrange>().GetState();

            short airId = GetLocalBlockId(air.Block.UnlocalizedName);

            short[,,] chunkData = new short[Chunk.ChunkSize, Chunk.ChunkHeight, Chunk.ChunkSize];

            void SetBlock(int x, int y, int z, BlockState s)
            {
                short id   = GetLocalBlockId(s.Block.UnlocalizedName);
                short meta = s.Block.GetMetaFromState(s);

#pragma warning disable CS0675 // Bitwise-or operator used on a sign-extended operand
                short value = (short)(id << 4 | meta);
#pragma warning restore CS0675 // Bitwise-or operator used on a sign-extended operand
                chunkData[x, y, z] = value;
            }

            bool IsAir(int x, int y, int z)
            {
                return(chunkData[x, y, z] >> 4 == airId);
            }

            for (int z = 0; z < Chunk.ChunkSize; z++)
            {
                for (int x = 0; x < Chunk.ChunkSize; x++)
                {
                    float wsX = chunk.Pos.WorldSpaceX();
                    float wsZ = chunk.Pos.WorldSpaceZ();

                    float xCh = x + wsX;
                    float zCh = z + wsZ;

                    int peakY = 32 + (int)Math.Abs(
                        MathHelper.Clamp(0.35f + _noiseUtil.GetPerlinFractal(xCh, zCh), 0, 1) * 32);

                    float grassSeed = _noiseUtil.GetPerlinFractal(-xCh * 32 + 8, -zCh * 32 + x * 8);

                    for (int y = peakY; y >= 0; y--)
                    {
                        if (y == peakY)
                        {
                            SetBlock(x, y, z, grass);

                            //set tallgrass above
                            if (IsAir(x, y + 1, z) && grassSeed >= 0.3f)
                            {
                                var random = MathUtil.NextFloat();

                                if (random >= 0 && random <= 0.6666)
                                {
                                    SetBlock(x, y + 1, z, tallgrass);
                                }
                                else
                                {
                                    SetBlock(x, y + 1, z, random <= 0.83325D ? tulipRed : tulipOrange);
                                }
                            }
                        }
                        else if (y > 0 && peakY - y > 0 && peakY - y < 3)
                        {
                            SetBlock(x, y, z, dirt);
                        }
                        else if (y == 0)
                        {
                            SetBlock(x, y, z, bedrock);
                        }
                        else
                        {
                            float f = _noiseUtil.GetNoise(xCh * 32 - y * 16, zCh * 32 + x * 16);

                            SetBlock(x, y, z, f >= 0.75f ? rare : stone);
                        }
                    }

                    //trees
                    float treeSeed = Math.Abs(MathHelper.Clamp(_noiseUtil.GetWhiteNoise(xCh, zCh), 0, 1));
                    //var treeSeed2 = Math.Abs(MathHelper.Clamp(0.35f + _noiseUtil.GetPerlinFractal(zCh, xCh), 0, 1));

                    if (treeSeed >= 0.85f && x >= 3 && z >= 3 && x <= 13 && z <= 13 && x % 4 == 0 && z % 4 == 0)
                    {
                        int treeTop = 0;

                        int height = (int)MathHelper.Clamp(peakY * treeSeed / 64f * 7.5f, 3, 4);

                        for (int treeY = 0; treeY < height; treeY++)
                        {
                            treeTop = peakY + 1 + treeY;
                            SetBlock(x, treeTop, z, log);
                        }

                        //leaves
                        for (int i = -3; i <= 3; i++)
                        {
                            for (int j = 0; j <= 3; j++)
                            {
                                for (int k = -3; k <= 3; k++)
                                {
                                    if (i == 0 && k == 0 && j <= 0)
                                    {
                                        continue;
                                    }

                                    int pX = x + i;
                                    int pY = treeTop + j - 1;
                                    int pZ = z + k;

                                    if (!IsAir(pX, pY, pZ))
                                    {
                                        continue;
                                    }

                                    Vector3 vec = new Vector3(i, j, k);

                                    float leavesSeed = (peakY - 32) / 32f;

                                    BlockState leaves = leavesGreen;

                                    if (leavesSeed > 0.2f && leavesSeed <= 0.4f)
                                    {
                                        leaves = leavesYellow;
                                    }
                                    else if (leavesSeed > 0.4f && leavesSeed <= 0.55f)
                                    {
                                        leaves = leavesOrange;
                                    }
                                    else if (leavesSeed > 0.65f)
                                    {
                                        leaves = leavesRed;
                                    }

                                    if (Vector3.Distance(vec, Vector3.Zero) <= 2.5f)
                                    {
                                        SetBlock(pX, pY, pZ, leaves);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(chunkData);

            chunk.GeneratedData(chunkData);

            if (updateContainingEntities)
            {
                foreach (Entity entity in Entities)
                {
                    BlockPos pos = new BlockPos(entity.Pos);

                    if (chunk.Pos == pos.ChunkPos())
                    {
                        int height = chunk.GetHeightAtPos(MathUtil.ToLocal(pos.X, Chunk.ChunkSize),
                                                          MathUtil.ToLocal(pos.Z, Chunk.ChunkSize));

                        if (entity.Pos.Y < height)
                        {
                            entity.TeleportTo(new Vector3(entity.Pos.X, entity.LastPos.Y = height, entity.Pos.Z));
                        }
                    }
                }
            }
        }
Example #5
0
 public void SaveTileEntity(BlockPos pos)
 {
     GetChunk(pos.ChunkPos())?.SaveTileEntity(ChunkPos.ToChunkLocal(pos));
 }
Example #6
0
 public TileEntity GetTileEntity(BlockPos pos)
 {
     return(GetChunk(pos.ChunkPos())?.GetTileEntity(ChunkPos.ToChunkLocal(pos)));
 }
Example #7
0
        public void GenerateChunk(ChunkPos chunkPos, bool updateContainingEntities) //TODO - something is causing this to be extremely slow and ran many times simultaneously for one chunk
        {
            Chunk chunk = CreateChunk(chunkPos, null);

            if (chunk == null)
            {
                return;
            }

            var air = BlockRegistry.GetBlock <BlockAir>().GetState();

            var leaves = BlockRegistry.GetBlock <BlockLeaves>().GetState();

            var log       = BlockRegistry.GetBlock <BlockLog>().GetState();
            var grass     = BlockRegistry.GetBlock <BlockGrass>().GetState();
            var dirt      = BlockRegistry.GetBlock <BlockDirt>().GetState();
            var stone     = BlockRegistry.GetBlock <BlockStone>().GetState();
            var rare      = BlockRegistry.GetBlock <BlockRare>().GetState();
            var bedrock   = BlockRegistry.GetBlock <BlockBedrock>().GetState();
            var tallgrass = BlockRegistry.GetBlock <BlockTallGrass>().GetState();

            short airId = GetLocalBlockId(air.Block.UnlocalizedName);

            short[,,] chunkData = new short[Chunk.ChunkSize, Chunk.ChunkHeight, Chunk.ChunkSize];

            void SetBlock(int x, int y, int z, BlockState s)
            {
                short id   = GetLocalBlockId(s.Block.UnlocalizedName);
                short meta = s.Block.GetMetaFromState(s);

                short value = (short)(id << 4 | meta);

                chunkData[x, y, z] = value;
            }

            bool IsAir(int x, int y, int z)
            {
                return(chunkData[x, y, z] >> 4 == airId);
            }

            for (int z = 0; z < Chunk.ChunkSize; z++)
            {
                for (int x = 0; x < Chunk.ChunkSize; x++)
                {
                    float wsX = chunk.Pos.WorldSpaceX();
                    float wsZ = chunk.Pos.WorldSpaceZ();

                    float xCh = x + wsX;
                    float zCh = z + wsZ;

                    int peakY = 32 + (int)Math.Abs(
                        MathHelper.Clamp(0.35f + _noiseUtil.GetPerlinFractal(xCh, zCh), 0, 1) * 32);

                    float grassSeed = _noiseUtil.GetPerlinFractal(-xCh * 32 + 8, -zCh * 32 + x * 8);

                    for (int y = peakY; y >= 0; y--)
                    {
                        if (y == peakY)
                        {
                            SetBlock(x, y, z, grass);

                            //set tallgrass above
                            if (IsAir(x, y + 1, z) && grassSeed >= 0.3f)
                            {
                                SetBlock(x, y + 1, z, tallgrass);
                            }
                        }
                        else if (y > 0 && peakY - y > 0 && peakY - y < 3)
                        {
                            SetBlock(x, y, z, dirt);
                        }
                        else if (y == 0)
                        {
                            SetBlock(x, y, z, bedrock);
                        }
                        else
                        {
                            float f = _noiseUtil.GetNoise(xCh * 32 - y * 16, zCh * 32 + x * 16);

                            SetBlock(x, y, z, f >= 0.75f ? rare : stone);
                        }
                    }

                    //trees
                    float treeSeed = Math.Abs(MathHelper.Clamp(_noiseUtil.GetWhiteNoise(xCh, zCh), 0, 1));
                    //var treeSeed2 = Math.Abs(MathHelper.Clamp(0.35f + _noiseUtil.GetPerlinFractal(zCh, xCh), 0, 1));

                    if (treeSeed >= 0.85f && x >= 3 && z >= 3 && x <= 13 && z <= 13 && x % 4 == 0 && z % 4 == 0)
                    {
                        int treeTop = 0;

                        int height = (int)Math.Clamp(peakY * treeSeed / 64f * 7.5f, 3, 4);

                        for (int treeY = 0; treeY < height; treeY++)
                        {
                            treeTop = peakY + 1 + treeY;
                            SetBlock(x, treeTop, z, log);
                        }

                        //leaves
                        for (int i = -3; i <= 3; i++)
                        {
                            for (int j = 0; j <= 3; j++)
                            {
                                for (int k = -3; k <= 3; k++)
                                {
                                    if (i == 0 && k == 0 && j <= 0)
                                    {
                                        continue;
                                    }

                                    int pX = x + i;
                                    int pY = treeTop + j - 1;
                                    int pZ = z + k;

                                    if (!IsAir(pX, pY, pZ))
                                    {
                                        continue;
                                    }

                                    Vector3 vec = new Vector3(i, j, k);

                                    if (MathUtil.Distance(vec, Vector3.Zero) <= 2.5f)
                                    {
                                        SetBlock(pX, pY, pZ, leaves);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            chunk.GeneratedData(chunkData);

            if (updateContainingEntities)
            {
                foreach (Entity entity in Entities)
                {
                    BlockPos pos = new BlockPos(entity.Pos);

                    if (chunk.Pos == pos.ChunkPos())
                    {
                        int height = chunk.GetHeightAtPos(MathUtil.ToLocal(pos.X, Chunk.ChunkSize), MathUtil.ToLocal(pos.Z, Chunk.ChunkSize));

                        if (entity.Pos.Y < height)
                        {
                            entity.TeleportTo(new Vector3(entity.Pos.X, entity.LastPos.Y = height, entity.Pos.Z));
                        }
                    }
                }
            }
        }