public ChunkColumn() { for (int i = 0; i < 16; i++) { _chunks[i] = PaletteChunk.CreateObject(); } isDirty = false; }
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;
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); }
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; } }