Example #1
0
        public ChunkColumn()
        {
            for (int i = 0; i < 16; i++)
            {
                _chunks[i] = PaletteChunk.CreateObject();
            }

            isDirty = false;
        }
Example #2
0
 public ChunkBase this[int chunkIndex]
 {
     get
     {
         ChunkBase chunk = _chunks[chunkIndex];
         if (chunk == null)
         {
             chunk = PaletteChunk.CreateObject();
             _chunks[chunkIndex] = chunk;
         }
         return(chunk);
     }
     set => _chunks[chunkIndex] = value;
Example #3
0
        public override object Clone()
        {
            PaletteChunk cc = CreateObject();

            cc._isAllAir = _isAllAir;
            cc._isDirty  = _isDirty;

            _blocks.CopyTo(cc._blocks, 0);
            _metadata.CopyTo(cc._metadata, 0);
            blocklight.Data.CopyTo(cc.blocklight.Data, 0);
            skylight.Data.CopyTo(cc.skylight.Data, 0);

            if (_cache != null)
            {
                cc._cache = (byte[])_cache.Clone();
            }

            return(cc);
        }
Example #4
0
        private void ParseSection(PaletteChunk section, ReadOnlySpan <byte> data)
        {
            var reader = new SpanReader();

            var version = reader.ReadByte(data);

            if (version != 8)
            {
                throw new Exception("Wrong chunk version");
            }

            var storageSize = reader.ReadByte(data);

            for (int storage = 0; storage < storageSize; storage++)
            {
                byte paletteAndFlag = reader.ReadByte(data);
                bool isRuntime      = (paletteAndFlag & 1) != 0;
                if (isRuntime)
                {
                    throw new Exception("Can't use runtime for persistent storage.");
                }
                int bitsPerBlock  = paletteAndFlag >> 1;
                int blocksPerWord = (int)Math.Floor(32d / bitsPerBlock);
                int wordCount     = (int)Math.Ceiling(4096d / blocksPerWord);

                int blockIndex = reader.Position;
                reader.Position += wordCount * 4;

                int paletteSize = reader.ReadInt32(data);

                var palette = new Dictionary <int, (short, byte)>();
                for (int j = 0; j < paletteSize; j++)
                {
                    var file = new NbtFile {
                        BigEndian = false, UseVarInt = false
                    };
                    var buffer = data.Slice(reader.Position).ToArray();

                    int numberOfBytesRead = (int)file.LoadFromStream(new MemoryStream(buffer), NbtCompression.None);
                    reader.Position += numberOfBytesRead;
                    var    tag       = file.RootTag;
                    string blockName = tag["name"].StringValue;
                    Block  block     = BlockFactory.GetBlockByName(blockName);
                    short  blockId   = 0;
                    if (block != null)
                    {
                        blockId = (short)block.Id;
                    }
                    else
                    {
                        Log.Warn($"Missing block={blockName}");
                    }
                    short blockMeta = tag["val"].ShortValue;
                    palette.Add(j, (blockId, (byte)blockMeta));
                }

                int nextStore = reader.Position;
                reader.Position = blockIndex;

                int position = 0;
                for (int wordIdx = 0; wordIdx < wordCount; wordIdx++)
                {
                    uint word = reader.ReadUInt32(data);
                    for (int block = 0; block < blocksPerWord; block++)
                    {
                        if (position >= 4096)
                        {
                            continue;                                           // padding bytes
                        }
                        int state = (int)((word >> ((position % blocksPerWord) * bitsPerBlock)) & ((1 << bitsPerBlock) - 1));
                        int x     = (position >> 8) & 0xF;
                        int y     = position & 0xF;
                        int z     = (position >> 4) & 0xF;
                        if (state > palette.Count)
                        {
                            Log.Error($"Got wrong state={state} from word. bitsPerBlock={bitsPerBlock}, blocksPerWord={blocksPerWord}, Word={word}");
                        }
                        short bid      = palette[state].Item1;
                        byte  metadata = palette[state].Item2;
                        if (storage == 0)
                        {
                            section.SetBlock(x, y, z, bid);
                            section.SetMetadata(x, y, z, metadata);
                        }
                        else
                        {
                            section.SetLoggedBlock(x, y, z, bid);
                            section.SetLoggedMetadata(x, y, z, metadata);
                        }
                        position++;
                    }
                }
                reader.Position = nextStore;
            }
        }